Escolar Documentos
Profissional Documentos
Cultura Documentos
Livro Programacao Orientada Objetos I 255-638426484013344944
Livro Programacao Orientada Objetos I 255-638426484013344944
PROGRAMAÇÃO E NOVAS
ORIENTADA
TECNOLOGIAS
A OBJETOS I
LIVRO-TEXTO
PROGRAMAÇÃO ORIENTADA
A OBJETOS I
Prof. Me. Robinson Crusoé da Cruz
2020
UNIARAXÁ - CENTRO UNIVERSITÁRIO DO PLANALTO DE ARAXÁ • TODOS OS DIREITOS RESERVADOS
2
FICHA CATALOGRÁFICA
FICHA CATALOGRÁFICA
Maria Clara Fonseca
Bibliotecária – CRB 6 / 942
ISBN: 978-85-99750-84-1
CDU: 004.421
COORDENAÇÃO
Coordenador EAD Prof. Me. Waldecy Lima
Núcleo Pedagógico Esp. Joice Aparecida Pereira
Profª. Ma. Ivana Lodi
EQUIPE MULTIDISCIPLINAR
Designers Instrucionais Esp. Fernanda de Mello Macedo
Revisores Textuais Profª. Drª. Adriene Coimbra
Profª. Ma. Nad Pereira
Prof. Dr. Nélio Araújo Martins
Diagramadores Tarcísio Fernando Antunes
Loren Cristiene dos Santos
Designers Multimídia Kariolando Januário da Silva
Suporte Técnico Raphael Lacerda
Suporte Acadêmico Esp. Evelin Figueiredo
Secretaria Marli Cruz
Naraiane Secundino
Não estão autorizadas nenhuma forma de reprodução, parcial ou integral deste material,
UNIARAXÁ - CENTRO
sem UNIVERSITÁRIO
autorização DO PLANALTO
expressa DE ARAXÁ • TODOS OS DIREITOS RESERVADOS
do UNIARAXÁ. 4
SUMÁRIO
SOBRE O AUTOR 7
GUIA DA DISCIPLINA 8
APRESENTAÇÃO DA DISCIPLINA 19
AULA 1 21
AULA 1 – INTRODUÇÃO À PROGRAMAÇÃO ORIENTADA A OBJETOS (POO) 22
FOLHA DE RESPOSTAS 54
CRÉDITOS 56
REFERÊNCIAS 57
AULA 2 58
AULA 2 - INTRODUÇÃO A LINGUAGEM C# E UMA REVISÃO SOBRE LÓGICA COMPUTACIONAL 59
AULA 2 - INTRODUÇÃO A LINGUAGEM C# E UMA REVISÃO SOBRE LÓGICA COMPUTACIONAL 60
REFERÊNCIAS 92
AULA 3 93
AULA 3 - DESENVOLVENDO SOFTWARE ORIENTADO A OBJETOS - PARTE I 94
DESENVOLVENDO SOFTWARE ORIENTADO A OBJETOS - PARTE I 95
FOLHA DE RESPOSTAS 122
REFERÊNCIAS 125
AULA 4 126
AULA 4 - DESENVOLVIMENTO DE SOFTWARE ORIENTADO A OBJETOS - PARTE II 127
PROJETOS POO E CONCEITOS 128
REFERÊNCIAS 154
AULA 5 155
AULA 5 - DESENVOLVENDO SOFTWARE ORIENTADO A OBJETOS - PARTE III 156
DESENVOLVENDO SOFTWARE ORIENTADO A OBJETOS - PARTE III 157
REFERÊNCIAS 182
AULA 6 183
AULA 6 - DESENVOLVENDO DE SOFTWARE ORIENTADO A OBJETOS - PARTE IV 184
Currículo: http://lattes.cnpq.br/7799575672355230
1. Iniciando os Estudos
Seja bem-vindo(a)!
Você está iniciando o estudo sobre Programação Orientada a Objetos I, uma disciplina curricular
do seu curso, que será desenvolvida na modalidade EAD (Educação a Distância).
VIDEOAULA
Além das informações/orientações contidas nesse Guia de
Disciplina, para uma ampla ambientação ao estudo dessa
disciplina, convidamos você a acessar o Tutorial do Ambiente
Virtual de Aprendizagem e a SAV (Sala de Aula Virtual) desta
disciplina, bem como a assistir à Videoaula de Apresentação da
disciplina Programação Orientada a Objetos I.
DICA DO AUTOR
Caso você tenha alguma dúvida sobre os procedimentos e/ou ações que
precisará realizar no decorrer do estudo dessa disciplina, é importante que entre
em contato com o(a) Tutor(a) do Curso e com seus colegas de turma no AVA
(Ambiente Virtual de Aprendizagem). Estamos preparados para atendê-lo(a),
ajudá-lo(a) a superar seus desafios e a atingir seus objetivos.
Objetivo Geral
• Desenvolver produtos de software e aprender sobre o paradigma orientado a objetos.
Objetivos Específicos
• Manipular strings.
Aula 3 - Desenvolvendo
• Trabalhar com listas e arrays.
software orientado a
• Desenvolver Projetos OO na linguagem C#.
objetos - Parte I.
• Estudar sobre a Manipulação dos tipos de dados.
Aula 7 - Programação
Orientada a Objetos • Estudar sobre aplicação de programação Orientada a
e as linguagens de Objetos em outras linguagens.
programação
• Revisar o conteúdo que foi estudado na disciplina.
Aula 8 - Revisando... • Desenvolver o Projeto Final da disciplina.
Assim, caso tenha críticas, comentários, sugestões ou elogios, acesse a SAV (Sala
de Aula Virtual) da disciplina e apresente-os para seus colegas de turma e para
o(a) Tutor(a) do Curso. Após reflexões, é possível que alterações sejam propostas
e efetivadas em benefício do processo de aprendizagem de todos!
Possui, portanto, uma carga horária total de 80 horas, conforme sugerido no Quadro-
cronograma, descrito a seguir:
COMPONENTES CARGA-
MODALIDADE CRONOGRAMA LETIVO
CURRICULARES HORÁRIA
Ambientação para o
2h EAD 1ª Semana
Estudo da Disciplina
Aula 1 9h EAD
2ª e 3ª Semanas
Aula 2 9h EAD
AC – Experiência de
Opcional: EAD e/ou
Aprendizagem Integrativa 2h 5ª Semana
Presencial
1 - Colaborativa
Aula 5 9h EAD
6ª e 7ª Semanas
Aula 6 9h EAD
Aula 7 9h EAD
8ª e 9ª Semanas
Aula 8 9h EAD
AC – Experiência de
Aprendizagem Integrativa 2h EAD 9ª Semana
2 - Individual
importante
Para confirmar as datas, efetivamente, agendadas para a realização da AC –
Colaborativa e Integrativa das Aulas 1 a 4 (opcional no Polo de Apoio Presencial ou
EAD), da AFPD (Avaliação Final Presencial da Disciplina), você deverá consultar o
Calendário Acadêmico; e, em caso de dúvidas, acessar o AVA (Ambiente Virtual
de Aprendizagem) para contatar o(a) Professor(a) da Disciplina!
AVALIAÇÕES
MODALIDADE NOTA
AC - Avaliação Continuada
Note que a sua NFD (Nota Final da Disciplina) é o resultado da soma das notas obtidas na
AC (Avaliação Continuada) e na AFPD (Avaliação Final Presencial da Disciplina), conforme
fórmula a seguir:
AC + AFPD = NFD
Sendo,
• AC = Avaliação Continuada
Assim, para a aprovação, sua NFD deverá ser igual ou maior que 7,0 (sete), com nota de AC
igual ou superior a 0,75 (setenta e cinco décimos).
importante
Para saber mais sobre a NFD (Nota Final da Disciplina), a Avaliação Substitutiva
(condições e taxas), as possibilidades de Recuperação, incluindo a Prova Final
(cujo aproveitamento poderá ser de 60% [nota≥6,0]), a DP (Dependência) e
sobre outros componentes curriculares, consulte o Manual Acadêmico; e, para
conferir suas notas consulte a Central Acadêmica do UNIARAXÁ.
Isso significa que, mesmo se tirar sete na AFPD, você só estará aprovado se tirar 0,75 ou mais
na AC (Avaliação Continuada). Em outras palavras, a participação no AVA (Ambiente Virtual
de Aprendizagem) será fundamental tanto para seu progresso no curso (já que a aprovação
também depende dela), quanto para o sucesso de seu processo de aprendizagem.
6. Bibliografia Básica
DICA DO AUTOR
As obras referenciadas nas Bibliografias Básica e Complementar, bem como da
Leitura Recomendada são importantes, tendo em vista a oportunidade para
ampliar e aprofundar seus conhecimentos sobre o tema de estudo dessa disciplina!
Assim, sugerimos que amplie as fronteiras de seu processo de aprendizagem,
consulte as obras indicadas!
MANZANO, José Augusto N. G. Programação de computadores C#. São Paulo: Érica, 2014.
SINTES, Anthony. Aprenda programação orientada a objeto em 21 dias. São Paulo: Makron
Books, 2002.
DAVID J. Barnes, Micheal Kölling. Programação Orientada a Objetos com Java - Uma introdução
prática usando o BLUEJ. Pearson, 2004.
DEITEL, H. M.; Deitel, P. J. C++ Como Programar: 3 ed. São Paulo: Bookman, 2001. 1098 p.
FOWLER, Martin. UML Essencial: um breve guia para linguagem padrão. Porto Alegre: Bookman,
2005.
8. Leitura Recomendada
CAELUM; Apostila de C# e Orientação a Objetos - Acesso em: 01/01/2019. Disponível em:
https://www.caelum.com.br
9. Sites Recomendados
DEVMEDIA. Site com Material sobre Desenvolvimento. Acesso em: 01/01/2019. Disponível
em: https://www.devimedia.com.br
STACKOVERFLOW. Site de pergunta e respostas sobre Tecnologia da Informação. Acesso
em: 01/01/2019. Disponível em: https://www.stackoverflow.com
DICA DO AUTOR
Para localizar os filmes, séries, vídeos e games referenciados, sugerimos que realize
buscas nos meios que, convencionalmente, que você utiliza para encontrar esses
recursos quando os busca por entretenimento. Muito além de um passatempo,
com os conhecimentos que está adquirindo com o estudo dessa e de outras
disciplinas do Curso, você poderá utilizá-los como fontes críticas para ampliar seus
conhecimentos de forma lúdica e contextualizada!
Estamos iniciando o estudo dos conteúdos sobre a disciplina Programação Orientada a Objetos
(POO) I, o qual ocorrerá ao longo de oito Aulas.
Na Aula 1, vamos estudar os conceitos básicos sobre programação orientada a objetos e a estrutura
das linguagens de programação.
Na Aula 2, vamos realizar uma revisão sobre lógica computacional e desenvolver alguns projetos
com o paradigma imperativo (estruturado) para que você possa conhecer a estrutura básica da
linguagem C#.
Na Aula 8, chegou a hora de criarmos o nosso projeto final. Nesta aula será proposto o desenvolvimento
de um projeto de software com os principais conceitos que foram abordados na disciplina.
Para que os conceitos teóricos e práticos possam ser bem compreendidos, é fundamental que
você faça estudos complementares por meio de textos e vídeo aulas disponíveis na web, resolva os
exercícios propostos e utilize os fóruns da comunidade de desenvolvedores para sanar suas dúvidas.
Agora que você deu o primeiro passo, espero que esteja preparado(a) para aprender sobre o
fantástico mundo da programação orientado a objetos. Lembre-se que, a compreensão desse
Bons estudos!
AULA 1
Objetivos:
Prezado(a) Aluno(a), seja bem-vindo(a) a mais uma disciplina. Na abordagem da Aula 1, sobre
Programação Orientada a Objetos, você irá identificar situações voltadas para os conceitos
sobre linguagens de programação, paradigmas de programação, programação orientada
a objetos e prática de abstração do mundo real para o mundo computacional. É importante
para o êxito profissional, que nessa aula você procure ler, e reler esse material, se necessário,
bem como consultar os materiais indicados, tentar resolver os exercícios propostos e solicitar
ajuda ao seu professor sempre que surgirem dúvidas. Empenhe-se em seus estudos e lembre-se:
o seu sucesso só depende de você.
INTRODUÇÃO À PROGRAMAÇÃO
ORIENTADA A OBJETOS (POO)
O QUE É LINGUAGEM DE
PROGRAMAÇÃO
HISTÓRICO DAS
LINGUAGENS DE
PROGRAMAÇÃO
LINGUAGEM DE BAIXO E
ALTO NÍVEL
NOMENCLATURAS DE PROGRAMAÇÃO
UMA LINGUAGEM DE IMPERATIVA
FALANDO SOBRE PROGRAMAÇÃO
LINGUAGEM DE PROGRAMAÇÃO
PROGRAMAÇÃO ORIENTADA A OBJETOS
PARADIGMAS DE
PROGRAMAÇÃO
PROGRAMAÇÃO
FUNCIONAL
PROGRAMAÇÃO
LÓGICA
LINGUAGEM
INTERPRETADA
CONSTRUÇÃO DE LINGUAGEM
PROGRAMAS COMPILADA
LINGUAGEM TRADUZIDA
VANTAGENS DA
PROGRAMAÇÃO
ORIENTADA A OBJETOS
PENSANDO EM OBJETOS
OBJETOS, CLASSES
E MÉTODOS
(COMPORTAMENTO)
PRATICANDO A
IDENTIFICAÇÃO DE
CLASSES
ESTRATÉGIA PARA
CONCEITOS
PROJETO DE SOFTWARE
FUNDAMENTAIS
ORIENTADO A OBJETOS
OS PILARES DA
PROGRAMAÇÃO
ORIENTADA A OBJETOS
PRATICANDO A
IDENTIFICAÇÃO
CLASSES,
MÉTODOS,ATRIBUTOS E
RELACIONAMENTO. CLASSE
DESENVOLVENDO
DIAGRAMA DE CLASSES
A Linguagem de Programação pode ser considerada uma estrutura utilizada para comunicar
com equipamentos, sejam computadores, tablets ou processadores. Por exemplo, o conjunto
de instruções de um processador pode ser entendido como uma Linguagem de Programação.
Entretanto, utilizar comandos com base na arquitetura de processadores se torna inviável. E
para facilitar a nossa vida como desenvolvedores, existem linguagens de programação de alto
nível para auxiliar no desenvolvimento de software (GUDWIN,1997).
LEMBRE-SE!
Algoritmo pode considerado uma sequência de passos para obter um objetivo. Algoritmo
possui entrada, processamento e saída. Por exemplo, ao utiliza um telefone público
como um “orelhão” ou similar, as operações que devemos realizar estão especificadas
junto a esse telefone, sendo mais ou menos assim:
1-leve o fone ao ouvido;
2-insira seu cartão no orifício apropriado;
3-espere o sinal para discar;
4-assim que ouvir o sinal, disque o número desejado;
5-ao final da ligação, retorne o fone para a posição em que se encontrava;
6- retire seu cartão.
Esse conjunto de operações é o que se denomina algoritmo. Qualquer pessoa pode
executar essas operações, na ordem especificada, para fazer suas ligações telefônicas,
desde que possua um cartão específico e conheça o número para o qual quer telefonar
(EDELWEISS, 2014).
Na década de 1950, começa a surgir a era das Linguagens de Ordem Mais Alta. A ideia era
tornar a tarefa de programação intuitiva para mais pessoas e criar linguagens para resolver
determinado grupos de problemas. As primeiras linguagens de ordem mais alta foram: Fortran,
Cobol, Algol e Lisp (TUCKER, 2009).
Fique atento, pois a Linguagem de Programação deve ser escolhida de acordo com domínio
do problema. Por exemplo, se for desenvolver um Jogo, existem linguagens que se adaptam
melhor a esse tipo de domínio.
importante
Fonte: (UFRN,2019)
Fonte: (USP,2019)
Desvantagens:
- Execução mais lenta, pois precisa interpretar o código fonte em tempo de execução,
ou seja, quando o software estiver em uso.
- Necessidade do código original (código fonte) para que ele seja executado.
Vantagens:
- Tem uma melhor performance relacionada ao tempo de execução, pois executa diretamente
no nível da máquina.
Desvantagem:
Vantagens:
Após este período inicial e com passar do tempo, ficou mais fácil identificar as práticas que
funcionavam na Programação Orientada a Objetos e surgiram várias linguagens com suporte
a este paradigma: Java, C++, C# entre outras. Atualmente, esse Paradigma é o mais utilizado
no mercado.
Imagine que você precisa organizar o seu guarda-roupa. Para isso, é necessário considerar as
roupas como o principal item que você terá que lidar. Então, o primeiro passo será organizar
as suas roupas. Entretanto, se você tentar colocar todos os tipos de objetos da classe roupa
no mesmo local, ainda não será o suficiente para deixar seu guarda-roupa organizado (FELIX,
2016).
A partir deste momento, você percebe que precisa de outra estratégia e decide encontrar
classes mais específicas para organizar seu guarda-roupa, pois você não quer guardar camisas
na mesma gaveta onde estão as calças. Então, você percebe que classificar por classes de
tipos de peças seria mais interessante para organizar o seu guarda-roupa, pois ao organizar por
tipo de peças, seria mais fácil de encontrar a camiseta da sua banda preferida (FELIX, 2016).
No exemplo anterior, abordamos um tema para você pensar em objetos concretos relacionados
ao mundo real. Entretanto, objetos também podem ser abstratos, por exemplo, essa disciplina
que você está cursando é um objeto abstrato da classe disciplina.
De que cor é o carro? Que velocidade ele pode alcançar? Quantas pessoas podem ocupar
este carro?
Você notará que não podemos responder a essas perguntas, a não ser que seja um carro
específico. A razão é que a palavra “carro”, nesse contexto, refere-se a classe carro, pois
estamos falando carro em geral e não um carro específico. Agora, se você relatar que o seu
carro está no estacionamento, podemos responder às perguntas acima, pois você sabe a cor,
a velocidade máxima e a capacidade de pessoas. Nesse momento, você pode definir que o
seu carro é um objeto da classe carro. Resumindo: objetos correspondem a elementos da vida
real e classes agrupam esses objetos.
Você pode analisar outro exemplo representado pela Figura 10, que representa uma classe
aluno e os alunos (objetos) Júlia e Pedro que derivam dessa classe. Nesse momento, é possível
notar que existem os atributos Nome e Idade que são comuns para os objetos da classe aluno.
No exemplo da Figura 11, temos uma classe livro e os objetos livro da Constituição Brasileira
e Código Da Vinci. Provavelmente, nesse momento você está pensando: mas existem várias
cópias do livro Código Da Vinci, então, ele pode ser uma Classe? Porém, note que, mesmo
que existam várias cópias do livro, os dados dos seus atributos (Título e data de publicação)
serão os mesmos, então, são o mesmo objeto. Mas, se for lançada uma segunda edição do
livro Código Da Vinci, esse novo lançamento será um novo objeto da classe Livro, pois possui a
data de publicação diferente.
Na Figura 12, temos um exemplo de classe de objetos abstratos. As disciplinas que você está
cursando são objetos da classe disciplina. Ao adicionar a disciplina Banco de Dados I, ela será
um objeto da classe disciplina.
Durante os exemplos de classe e objetos comentamos sobre atributos que podem ser
considerados como propriedades das classes e que podem ser preenchidos pelos objetos. Por
exemplo, toda classe disciplina pode ter nome e data de cadastro, então estes dois itens são
chamados de atributos da classe disciplina.
Além de atributos, uma classe pode conter comportamentos (Métodos), que é uma ação
executada por um objeto quando recebe uma mensagem ou em resposta a uma mudança
de estado, ou seja, é algo que o objeto faz. Ao analisar o exemplo da classe Aluno (Figura 5),
seria possível citar alguns comportamentos da vida real, como: andar, estudar. E ao analisar a
classe disciplina (Figura 6) é possível citar alguns comportamentos do mundo computacional
que fazem parte do ambiente do AVA: SalvarDados, PesquisarDados e ExcluirDisciplina.
importante
A Figura 13 representa uma estrutura de relacionamento entre classes que mostra o cenário de
vendas. Perceba que, esses objetos interagem uns com os outros para orientar a estrutura do
programa. Por exemplo, quando for fechar a venda, o objeto caixa precisa analisar o preço
de todos os itens vendidos.
Fonte: (ALVES,2019).
Herança: posso ter uma classe aluno, mas aluno é algo muito generalista, então, é possível criar
classes que sejam filhas (subclasses) da classe Aluno, por exemplo, Graduação e Mestrado
(Figura 9) herda da classe Aluno. Então, na classe Aluno são adicionados atributos e métodos
(comportamentos) que são comuns a qualquer aluno. E nas classes filhas (subclasse) mestrado
e graduação, são adicionado somente o que é especialidade dessa classe. Geralmente, a
herança é chamada de Generalização e Especialização.
importante
Fonte: (MELO,2006)
2.9.1 - CLASSE
A Figura 17 representa um exemplo de Diagrama de Classe com vários elementos da notação
de tal Diagrama. Vamos identificar alguns elementos, por exemplo: ao entrar no fórum você
possui a opção para criar um tópico no fórum e quando acessar o AVA, você é uma pessoa,
mas do tipo Aluno e não Professor. É visível a similaridade desse diagrama com mundo real, não
é verdade?
+ public (público): indica que o elemento da classe pode ser utilizado livremente por outras
classes do mesmo ou de outro pacote. Na Figura 11, a classe Pessoa tem acesso a classe
Tópico Fórum, e como os métodos Postar(), Enviar Email() e Excluir() são públicos (+), a classe
Pessoa pode utilizar estes métodos.
~ package (pacote): indica que os métodos e atributos da classe podem ser utilizados
livremente por outras classes pertencentes ao mesmo pacote. Este tipo de visibilidade é utilizado
exclusivamente na linguagem JAVA. O objetivo é separar a visibilidade de acordo com um
grupo de classes. Por exemplo, o software do UNIARAXÁ pode ser separado por pacotes de
classes de acordo com setores: acadêmico e financeiro.
- private (privado): indica que os métodos e atributos podem ser manipulados apenas pela
própria classe. Perceba que a classe Aluno possui um atributo RA com visibilidade protegida (-).
Então, nenhuma classe externa terá acesso a esse atributo.
Associação binária
Este tipo de associação acontece entre duas classes. Os exemplos abaixo (Figura 19)
representam alguns tipos de relacionamento do tipo binário. No primeiro exemplo, é utilizada
uma linha simples para definir o relacionamento entre as classes. No segundo exemplo, é
utilizada uma seta para deixar claro quem possui acesso a qual classe. Nesse exemplo, a
classe Funcionário aponta para a classe Dependente, isso define que a classe Funcionário terá
acesso ao conteúdo da classe Dependente, porém a classe dependente não terá acesso ao
conteúdo da classe Funcionário. No último exemplo, o triângulo e o verbo definem o sentido
da leitura do diagrama, neste exemplo, a leitura correta seria: “dependente, depende do
funcionário” (BOOCK,2006).
Antes de falar dos outros tipos de associação (relacionamento), vamos aprender sobre o grau
de multiplicidade entre as classes. Note que no diagrama (Figura 13), além do relacionamento,
é possível definir o grau de multiplicidade. Por exemplo, o Dependente pode depender apenas
de um Funcionário (1), por outro lado, o Funcionário pode ter nenhum ou vários dependentes
(*) (BOOCK,2006). A Figura 20 representa os tipos de grau de multiplicidade que podem ser
utilizados.
Neste tipo de relacionamento, a classe relaciona-se com ela mesma, por exemplo, um
funcionário pode chefiar um ou mais funcionários (Figura 21). Este tipo de relação, na maioria
das situações, pode ser substituído por um relacionamento binário, neste exemplo, poderia
existir uma classe Funcionário e outra classe Chefia (BOOCK,2006).
Associação de agregação
Composição
Figura 23 - Composição
Generalização
Este tipo de associação é utilizado para identificar classes ancestrais, chamadas de gerais e
classe herdeiras, chamadas de especializadas. Este tipo de relacionamento permite também
demonstrar a ocorrência de Métodos Polimórficos. No exemplo (Figura 24), a classe Pessoa
possui tudo o que é comum para as classes Aluno e Professor. Nas classes Aluno e Professor, é
adicionado somente aquilo que é especialidade delas (BOOCK,2006).
Utilizada quando ocorrem associações que possuem relacionamentos de muitos para muitos
(*). No exemplo (Figura 25), existe um relacionamento de muitos para muitos entre Ator e Filme,
então surge a necessidade de criar uma terceira classe para detalhar o relacionamento. A
classe Atua foi criada para controlar o papel que o ator terá no Filme (BOOCK,2006).
Dependência
A ideia é definir que uma classe possui uma dependência de existência de outra classe. No
exemplo (Figura 26), a classe item Carrinho dependente da existência da classe Carrinho
Compra (BOOCK,2006). Atenção, pois esse tipo de relacionamento não costuma ser utilizado.
Apresentamos nesse tópico, um resumo sobre Diagrama de Classes. Contudo, existem outros
elementos que não foram abordados neste momento e serão apresentados nas próximas aulas
da disciplina.
DICA DO AUTOR
Existem várias ferramentas para criação de Diagrama de Classe. O Astah é uma
dessas ferramentas. Faça o download da versão gratuita, clicando aqui.
Exercício 6 - Funcionários
Uma empresa precisa de um sistema para armazenar os dados dos funcionários
e dependentes. Os dados dos funcionários a serem armazenado são o nome, o
CPF e a data de nascimento. Para o dependente, deseja-se armazenar o nome e
a data de nascimento. Além disso, a empresa determinou que cada funcionário
pode ter no máximo cinco dependentes.
Nessa aula, foi apresentada uma abordagem inicial sobre Programação Orientada a
Objetos. Discutimos sobre Diagrama de Classe, que faz parte da UML (Linguagem de
Modelagem Unificada), conteúdo amplamente discutido em outras disciplinas desse
curso.
aUTOaVALIAÇÃO
Após essa aula, você é capaz de identificar a diferença entre os Paradigmas
de Programação? Sabe aplicar conceitos de abstração na modelagem de
software orientado a objetos? Consegue distinguir os diversos conceitos
sobre Linguagem de Programação? Caso você consiga responder essas
questões, parabéns! Você atingiu os objetivos específicos da Aula 1! Caso
tenha dificuldades para responder algumas delas, aproveite para reler o
conteúdo da aula, acessar o UNIARAXÁ Virtual e interagir com seus colegas,
tutor (a) e professor (a). Você não está sozinho nessa caminhada! Conte
conosco!
RECAPITULANDO
Caro(a) Aluno(a), chegamos ao fim da nossa aula. Esperamos que tenha compreendido os
conceitos da Programação Orientada a Objetos e tenha resolvido os exercícios disponibilizados
nessa aula.
Muito bem! Em nossa próxima Aula, veremos uma introdução sobre a Linguagem de
Programação C# e vamos começar a desenvolver nossos primeiros programas.
VIDEOAULA
Após a leitura e o estudo do seu livro-texto, chegou o momento de
complementar seu conhecimento. Vá até seu Ambiente Virtual
de Aprendizagem e acesse a Videoaula referente à Aula.
Exercício 6 - Funcionários
BOOCK, Grandy; RUMBAUGH, James; JACOBSON , Ivar. UML guia do usuário: o mais avançado
tutorial sobre Unified Modeling Language (UML), elaborado pelos próprios criadores da
linguagem. 2 ed. Rio de Janeiro: Campus, 2006.
EDELWEISS, Nina; LIVI, Maria Aparecida Castro. Algoritmos e programação com exemplos em
Pascal e C. 2014.
MANZANO, José Augusto N. G. Programação de computadores C#. São Paulo: Érica, 2014.
SILVA, Ricardo Pereira. UML 2: modelagem orientada a objetos. Visual Books, 2007.
SINTES, Anthony. Aprenda programação orientada a objeto em 21 dias. São Paulo: Makron
Books, 2002.
AULA 2
Objetivos Específicos:
Fique atento(a)! Todos os exercícios desenvolvidos e propostos nesta aula, estão disponíveis no
AVA (Ambiente Virtual de Aprendizado).
Espero que esteja curioso para iniciar seus estudos no fantástico mundo da linguagem C#.
Boa aula!
AULA 2 - INTRODUÇÃO A
LINGUAGEM C# E UMA REVISÃO
SOBRE LÓGICA COMPUTACIONAL
Plataforma .NET
HISTÓRIA DA LINGUAGEM
C#
CRIANDO O PRIMEIRO
PROGRAMA EM C#
ESTRUTURA DAS CLASSES E
DA LINGUAGEM
VARIÁVEL NA LINGUAGEM
DE PROGRAMAÇÃO
OPERADORES
ARITMÉTICOS, TIPOS DE
DADOS E COMANDOS DE
TIPOS DE DADOS NA SAÍDA E ENTRADA
LINGUAGEM C#
ENTRADA E SAÍDAS DE
DADOS
CONSTRUÇÃO DE
PROGRAMAS C#
CONVERSÃO ENTRE TIPO
DE DADOS E ENTRADA DE DESVIO CONDICIONAL
DADOS SIMPLES
DESVIO ENCADEADO
ESTRUTURA REPETITIVA
USANDO WHILE
ESTRUTURA REPETITIVA
ESTRUTURA REPETITIVA
USANDO FOR
saiba mais!
.NET Core é uma estrutura de código aberta para desenvolvimento de software para
sistemas operacionais Windows, Linux e MacOS. Possui suporte para C#, F# e outras
linguagens.
Figura 4 - Frameworks
Fonte: (MICROSOFT,2018)
importante
saiba mais!
Antes do seu lançamento, a linguagem C# se chamava Cool. Atualmente, C# pode
ser utilizado no desenvolvimento de aplicativos para dispositivos móveis por meio do
Xamarin.
saiba mais!
No passado, os desenvolvedores de software utilizavam apenas um editor de texto para
escrever seus programas. Atualmente, temos a facilidade de utilizar ferramentas IDEs
que auxiliam na produtividade e outras atividades relacionadas ao desenvolvimento de
software, por exemplo, a possibilidade de realizar testes automatizados.
Agora que você já realizou o download do Visual Studio Community, vamos realizar a instalação.
A seguir, são apresentados os principais passos da instalação.
Primeira etapa (Figura 5): é mostrada uma mensagem sobre os termos de licença e da política
de privacidade da Microsoft.
Segunda etapa (Figura 6): nesta etapa é possível personalizar sua instalação, ou seja, neste
momento você pode definir quais os recursos você deseja utilizar. Quanto maior a quantidade
de recursos, maior o consumo de memória e o processamento da máquina. Durante a disciplina,
vamos utilizar projetos desenvolvidos no Console, Windows Forms e Web. Então marque as
alternativas relacionadas com esses tipos de projetos.
Terceira Etapa (Figura 7): nesta etapa é possível instalar os pacotes de idiomas opcionais.
DICA DO AUTOR
Na área de TI você será obrigado a utilizar o inglês, então, utilize todas as ferramentas
e recursos neste idioma. Esta é uma das melhores formas de realizar uma imersão e
aprender os termos em inglês utilizados na área da computação.
Figura 7 - Idiomas
Fantástico! Com a ferramenta instalada e pronta para ser utilizada, vamos desenvolver o nosso
primeiro programa na linguagem C#.
A seguir vamos conhecer os passos para você criar o seu primeiro programa na linguagem C#.
Passos:
3 - Após criar o projeto, é apresentado a tela (Figura 10) com a classe Program que é a primeira
classe a ser executada quando o programa é iniciado. Então adicione os comandos da linha 8
e 9 (Figura 10) que são responsáveis por mostrar uma mensagem “Hello World” na tela e realizar
uma pausa (aguarda uma tecla ser pressionada).
Como este programa foi construído: durante a execução deste exemplo, o Visual Studio analisou
se existia erro de sintaxe. No segundo passo, o compilador gerou o código intermediário (CIL
- Common Intermediate Runtime). Depois o tradutor CLR (Common Language Runtime) gerou
um arquivo executável (exe). Por último, o Visual Studio executou o assembly gerado e em
seguida o CLR carregou o código CIL que foi gerado pelo compilador, e por fim, o código foi
executado no Sistema Operacional.
Parabéns!!!! Este foi seu primeiro exemplo utilizando a linguagem C#, a seguir vamos estudar
alguns conceitos sobre variáveis e tipos de dados. Em seguida, teremos outros exemplos para
exercitarmos sobre lógica de programação.
Você e seu amigo precisam realizar uma conta. Então, você diz: ”Vamos somar dois números?
”. E continua: “O primeiro número é 5”. Seu amigo guarda o primeiro número na “cabeça”, ou
seja, na memória. Então você diz: “O segundo número é 3”. Então seu amigo também guarda
o segundo número na memória, sem esquecer o primeiro número, ou seja, cada número foi
armazenado em posições diferentes da memória humana, sem sobreposição. Então, você
pergunta: “Qual é o resultado da soma?”. Seu amigo resgata os valores armazenados na sua
memória, realiza a conta e responde dizendo que o resultado é 8 (ASCENCIO, 2008).
Você deve estar pensando: existe uma relação da memória humana e variáveis? Sim, pois
Durante o desenvolvimento de software você será obrigado a criar várias variáveis, por exemplo,
se for desenvolver um programa simples para calcular a soma de dois valores inteiros, você
provavelmente irá utilizar três variáveis, duas para os valores a serem somados e uma para
armazenar o resultado. Veja que este procedimento é idêntico ao realizado pela memória
humana e estas variáveis criadas no computador irão consumir uma parte da memória do
computador.
Por outro lado, além de saber o que significa variável, você precisa conhecer e definir qual o
tipo de dado que será armazenado para reservar um espaço compatível com este tipo. Por
exemplo, se for armazenar um número inteiro é preciso definir que a variável é compatível com
este tipo. A seguir serão apresentados os principais tipos de dados utilizados na linguagem C#.
saiba mais!
Existem vários estudos relacionados à computação quântica para tentar substituir a
forma binária utilizada para armazenar dados. Para aprender mais sobre computação
quântica, assista ao vídeo do Professor da USP, Frederico Borges de Brito: https://youtu.
be/SA51x26sKqc.
! FIQUE ATENTO!
Tipos de valor
Tipos simples:
- Integral sem sinal: byte, ushort, uint,ulong
- Caracteres Unicode: char
- Ponto flutuante IEEE: float, double
- Decimal de alta precisão:decimal
- Booleano: bool
Tipos enum:
- Tipos definidos pelo usuário do formulário enum E {...}
Tipos struct:
- Tipos definidos pelo usuário do formulário struct S {...}
Tipos de valor anuláveis:
- Extensões de todos os outros tipos de valor com um valor null
Tipos delegados
- Tipos definidos pelo usuário do formulário delegate int D(...)
Fonte: Elaborado pelo Autor.
A Figura 13 representa um resumo dos tipos mais utilizados na linguagem C#. Nesse exemplo,
você pode analisar a faixa de dados permitida para cada tipo, por exemplo, um tipo booleano
pode receber os valores true e false e o tipo Sbyte pode receber valores entre 0 a 255.
No C# você pode utilizar declarações de tipos para criar novos tipos. Uma declaração de tipo
especifica o nome e os membros do novo tipo. Cinco das categorias do C# de tipos, são tipos
definidos pelo usuário: classe, struct, interface, enum e delegados (MICROSOFT,2016).
a) Um tipo classe define uma estrutura de dados que contém atributos, métodos e
outras características. Este tipo fornece suporte para as características necessárias
para que uma classe tenha as características da programação orientada a
objetos (MICROSOFT,2016).
b) Um tipo struct tem características idênticas a uma classe, porém, diferente das
classes, as structs são tipos de valor e, normalmente, não precisa de alocação
de heap (FIGURA X). Além disso, não possui suporte a várias características da
programação orientada a objetos, por exemplo, herança (MICROSOFT,2016).
d) O tipo delegate representa referências aos métodos com uma lista parâmetros
e tipo de retorno específicos. Objetos delegados possibilitam o tratamento de
métodos como entidades que possam ser atribuídas a variáveis e passas como
parâmetro (MICROSOFT,2016).
CONECTANDO
Agora vamos realizar uma revisão básica sobre Lógica Computacional e um estudo
sobre a estrutura da linguagem C#. Então, neste momento é importante que você
tente resolver os exercícios, pois o conteúdo desta aula servirá como base para as
próximas aulas.
Na Figura 14, temos um exemplo da classe Program. Entre as Linha 1 e 5 estão as declarações
dos namespaces, que podem ser considerados estruturas pré-definidas ou bibliotecas que
podem ser utilizadas pela classe. Por exemplo, se fosse retirado a linha 1 (using System;), para
executar os comandos das linhas 13 e 14, seria necessário adicionar o caminho completo:
System.Console.WriteLine(“Hello Word”). Além disso, note que os namespace que não foram
utilizados estão na cor cinza (linha 2 a 5). Na linha 7, temos o namespace da classe, denominado
primeiroExemplo. Esta característica pode ser utilizada para agrupar as classes, por exemplo, as
Como foi apresentado no início desta aula, a linguagem C# é case sensitive, ou seja, diferencia
palavras maiúsculas de minúsculas. Outro fato é que, a linguagem C# possui na sua sintaxe a
necessidade da utilização de ponto e vírgula para encerrar a execução de cada instrução.
Além disso, note que na linha 12 possui uma chave de abertura do contexto do método Main
e na linha 15, uma chave fechando o contexto, ou seja, tudo o que está entre as linhas 12 e 15
fazem parte do mesmo contexto.
Você deve estar pensando: temos apenas uma classe em um programa console? A resposta
é Não. Como qualquer linguagem orientada a objetos é possível criar várias classes, seja no
mesmo arquivo ou arquivos diferentes. A Figura 15 representa como seria a estrutura das classes
dentro de uma aplicação em C#. O exemplo representa parte de uma aplicação acadêmica
e de uma biblioteca que pertencem ao mesmo produto de software, porém, estão organizadas
por namespace de acordo com a categoria das classes.
importante
No exemplo de código da Figura 16, você pode analisar alguns tipos de dados utilizados na
linguagem C#. Note que foi utilizado o comando Console.WriteLine() para escrever os valores
na tela do console. Nas linhas 20 e 21 utilizamos o int.MaxValue e int.MinValue, que mostram
qual o limite máximo e mínimo de uma variável. O comando Console.ReadLine() utilizado para
leitura de entrada de dados, neste contexto, serviu para pausar a tela até que uma tecla seja
pressionada.
Neste momento, você precisa conhecer algumas regras de sintaxe e de boas práticas na
definição de variáveis:
importante
Além dos operadores aritméticos comuns, na linguagem C# você pode utilizar operadores
aritméticos de atribuição, que representam uma forma resumida de atribuição de valores. No
programa da Figura 17 ,nas linhas 19 e 20, utilizamos alguns operadores de atribuição. A Tabela
4, representa os principais operadores de atribuição da Linguagem C# .
O programa apresentado pela Figura 18 realiza a soma de duas variáveis denominadas IdadeA
e IdadeB. Em seguida, é apresentado a soma das idades na tela. Neste exemplo, os valores da
idadeA e idadeB devem ser digitados pelo usuário. O comando Consolde.ReadLine() realiza
uma leitura do valor digitado. Note que na linha 15, o valor digitado pelo usuário é lido e
armazenado na variável nome. Como todo valor de entrada é do tipo string, na leitura das
idades A e B (linha 19 e 22) foi necessário realizar um Parse (int.Parse()) para converter o valor
String para int.
VAMOS PRATICAR?!
EXERCÍCIO RESOLVIDO 1:
Observação: A resolução deste exercício está disponível no final desta aula e o código está
disponível no AVA.
Conversões definidas pelo usuário: as conversões definidas pelo usuário são realizadas por
métodos especiais que podem ser definidos para habilitar conversões explícitas e implícitas entre
tipos personalizados que não têm uma relação de classe base/classe derivada (MICROSOFT,
2018).
Conversões com classes auxiliares: para converter entre tipos não compatíveis, assim como
inteiros e objetos System. DateTime, ou cadeias de caracteres hexadecimais e matrizes de
bytes, você pode usar a classe System.BitConverter, a classe System.Convert e os métodos
Parse (MICROSOFT, 2018).
importante
saiba mais!
As variáveis das linguagens Javascript, PHP e Python não são tipadas, isto significa que
elas não possuem tipo ao serem criadas.
Operadores Lógicos em C#
V1 V2 V1 && (E) V2 V1 || (OU) V2 ! (NÃO) (V1)
F F F F V
F V F V V
V F F V F
V V V V F
Fonte: Elaborada pelo autor.
if <condição>{
<instrução 1>
<instrução 2>
}
A seguir, temos um exemplo (Figura 20) de desvio condicional simples utilizado na linguagem
C#. Veja que somente aparecerá uma mensagem na tela se o valor de A for maior do que B.
Neste exemplo a condição é verdadeira, pois, perceba que na linha 15 é realizado um teste
onde A é maior do que B, então a execução das linhas 16 e 17 será realizada.
if <condição>{
<instrução 1>
<instrução 2>
<instrução N>
}else{
<instrução 1>
<instrução 2>
<instrução N>
}
Neste Exemplo, a condição é verdadeira, então a mensagem “Maior” será exibida na tela do
console.
if (<condição 1>) {
<instrução 1>
<instrução 2>
<instrução N>
}
else if (<condição 2>) {
<instrução 1>
<instrução 2>
<instrução N>
}
else {
<instrução 1>
<instrução 2>
<instrução N>
}
O interessante é que você pode substituir esta estrutura por três estruturas simples, porém, com
a desvantagem de ter uma performance inferior a estrutura encadeada, pois em algumas
situações seriam realizados testes desnecessários.
VAMOS PRATICAR?!
EXERCÍCIO RESOLVIDO 2:
Observação: A resolução deste exercício está disponível no final desta aula e o código está
disponível no AVA.
O exemplo (Figura 23) a seguir, mostra dez mensagem na tela com os valores de 1 a 10. Note
que na linha 2, foi adicionado um comando para incrementar o valor de B. Cada vez que o
código passar por esta linha, o B aumento um dígito, e isto garante que a repetição finalize
quando chegar no valor 11. Então, a repetição das linhas 18 e 19 serão realizadas enquanto a
condição do while (linha 16) for verdadeira.
VAMOS PRATICAR?!
EXERCÍCIO 3 (RESOLVIDO):
Observação: A resolução deste exercício está disponível no final desta aula e o código está
disponível no AVA.
do {
<instrução 1>
<instrução N>
}while (<condição 1>)
for (início;condição;incremento) {
<instrução 1>
<instrução N>
}
O exemplo (Figura 24) a seguir, mostra na tela todos os dígitos entre 1 e 10. Note que o comando
I++ realiza o incremento para tornar a condição (I<=10) falsa.
CUIDADO aulas.
VAMOS PRATICAR?!
EXERCÍCIOS SUGERIDOS
• Uma pessoa só pode votar em eleições brasileiras se ela for maior que 16 anos e for
cidadã brasileira. Crie um programa com duas variáveis, int idade, bool brasileira , e
faça com que o programa diga se a pessoa está apta a votar ou não, de acordo com
os dados nas variáveis (CAELUM,2019).
FOLHA DE RESPOSTAS
Exercício 01
Comentários: Para resolver este exercício você pode utilizar desvios encadeados.
Exercício 03
RECAPITULANDO
Caro(a) Aluno(a), chegamos ao fim da nossa aula. Espero que tenha compreendido o conteúdo
e resolvido os exercícios propostos. Inicialmente estudamos sobre a estrutura da tecnologia
.NET, com objetivo de compreender como um programa é construído nesta plataforma. Nas
etapas seguintes, estudamos sobre a linguagem C#, tipos de dados e variáveis. Em seguida,
estudamos sobre comandos de entrada e saída, conversão de tipos de dados, comandos
condicionais e repetitivos.
Muito bem! Em nossa próxima Aula, vamos iniciar o estudo e desenvolvimento de programas
orientado a objetos.
VIDEOAULA
Após a leitura e o estudo do seu livro-texto, chegou o momento de
complementar seu conhecimento. Vá até seu Ambiente Virtual
de Aprendizagem e acesse a Videoaula referente à Aula.
MANZANO, José Augusto N. G. Programação de computadores C#. São Paulo: Érica, 2014.
AULA 3
Objetivos Específicos:
• Manipular strings.
• Trabalhar com listas e arrays.
• Desenvolver Projetos OO na linguagem C#.
• Estudar sobre a Manipulação dos tipos de dados.S
Através dos estudos dessa Aula você será capaz de aplicar conceitos iniciais de Programação
Orientada a Objetos e entre outros conceitos e estruturas da linguagem C#. Você sabe
manipular strings e datas? Sabe criar e utilizar métodos? Nessa aula você terá a resposta para
essas e outras perguntas.
Fique atento(a), pois as resoluções dos exercícios resolvidos estão disponíveis no AVA (Ambiente
Virtual de Aprendizado).
Espero que esteja curioso para iniciar no fantástico mundo da Programação Orientada a
Objetos!
Boa aula!
DESENVOLVENDO SOFTWARE
ORIENTADO A OBJETOS - PARTE I
VETORES DIMENSIONAIS
ARRAY
MULTIDIMENSIONAL COMANDO
CONDICIONAL COM
SWITCH CASE
CONCATENANDO
STRINGS C#
FORMATANDO VALORES
COM MÉTODO STRING.
FORMAT
TRABALHANDO COM
DATAS EM C#
ORGANIZANDO O
CLASSES E OBJETOS
CÓDIGO COMO CLASSE
MÉTODO SEM RETORNO E
SEM PARÂMETROS
Você deve ter percebido que, para realizar a média de 10 alunos utilizando a mesma estrutura
do Algoritmo da Figura 1, seria necessário adicionar mais sete variáveis e uma mensagem para
cada variável a ser preenchida pelo usuário.
Perceba que o array possui índice para que seja possível alterar ou selecionar cada valor dentro
O código a seguir representa a inserção dos valores no array da Figura 2. Perceba que
inicialmente, é criado um vetor (array) com 5 posições e, em seguida, são inseridos os valores
em cada posição.
Vamos voltar ao nosso problema do cálculo da idade dos alunos da disciplina de POO.
Utilizaremos um vetor (array) para armazenar a idade de 10 alunos de uma determinada
disciplina. Diferente do exemplo apresentado anteriormente para inserir em um vetor (array)
de cinco posições. Neste exemplo, iremos otimizar o nosso código para tornar a resolução mais
dinâmica.
No exemplo da Figura 4, foi criado um array com dez posições para armazenar os dados da
• Na linha 14, é criado uma variável do tipo vetor (array), neste momento, a estrutura
ainda não foi criada, ou seja, foi criado apenas um ponteiro do tipo vetor (array).
LEMBRE-SE!
Em relação ao heap, na Linguagem C#, existem dois “agrupamentos”
de tipos de dados. No primeiro grupo, são agrupados os tipos por
valor, onde o espaço reservado na memória (stack) é utilizado para
armazenar o valor. O segundo grupo é considerado de referência,
pois o endereço das variáveis na memória é utilizado para armazenar
o endereço onde os dados estão armazenados (heap). Para mais
detalhes, consulte a aula 02.
• Na linha 17, temos um comando repetitivo, com a variável i iniciando com valor 0 (i=0),
pois a primeira posição do vetor (array) é zero. Na mesma linha, a cada execução o i é
incrementado em uma unidade (i++) e um teste é realizado para analisar se chegou no
final do vetor (array) (i<A.Length). Lenght é uma propriedade do vetor que retorna o seu
tamanho. Então, como o índice começa na posição 0, a execução será até i ser igual
9, que representa a última posição do vetor (array).
LEMBRE-SE!
Caso esteja com dúvida em relação aos comandos repetitivos (for,
while e do while), seria interessante voltar na aula 02 e estudar os
exemplos apresentados.
• Na linha 19, é mostrada uma mensagem na tela para solicitar a inserção da idade dos
alunos.
• Na linha 20, é armazenado o valor na posição i do vetor A. Por exemplo, na primeira vez
que o comando de repetição for executado e considerando que a idade digitada será
33, a linha de código terá a seguinte estrutura: A[1] = 33.
Você conseguiu analisar a diferença entre os exemplos da Figura 1 e 3? Note que, no exemplo
3, para alterar a quantidade de alunos seria necessário alterar apenas a linha 15 com a
quantidade de elementos do vetor, por exemplo, int[20]. Por outro lado, no exemplo da Figura
1, para armazenar 20 idades, seria necessário criar ao todo, 20 variáveis e 20 instruções para
receber os valores digitados pelo usuário. Então, é bem mais fácil utilizar o vetor (array), não é
verdade?
VAMOS PRATICAR?!
Desenvolva um programa utilizando a Linguagem C# para
armazenar em um array o salário de 12 meses de trabalho de uma
pessoa. No final, apresentar o valor da média na tela.
2. ARRAY MULTIDIMENSIONAL
No exemplo explicado na Seção anterior, analisamos como criar um vetor (array). Entretanto,
é possível criar um array que possua mais de uma dimensão como, por exemplo, um array
com duas dimensões, que neste caso, é chamado de Matriz. A Figura 5 representa um array
(matriz) multidimensional com quatro linhas e três colunas. Para você acessar os elementos,
será necessário utilizar dois índices: o primeiro que define a linha e o segundo que define a
coluna.
O exemplo da Figura 6, representa uma estrutura utilizada para armazenar valor em um array
Note que, a diferença básica entre preencher os dados de um vetor (array) dimensional em
multidimensional está na quantidade de índices e nos comandos de repetição. No array
dimensional é preciso apenas de um comando de repetição. Já na matriz (array) com duas
dimensões (multidimensional) são necessários dois comandos de repetição aninhados. Ou
seja, precisaremos invocar um comando repeticional (for), que percorrerá as linhas e outro
comando repeticional (for), que percorrerá as colunas.
! FIQUE ATENTO!
Os dois exemplos (Figura 8) representam uma estrutura utilizando o if else estruturado e uma
alternativa similar, utilizando a estrutura switch case, que pode ser utilizada como alternativa do
desvio condicional estruturado.
Note que, no exemplo do switch case, a variável sexo é analisada em cada linha de instrução
case. E no final, caso nenhuma condição (case) seja verdadeira, a estrutura dentro do default
é executada.
• Na linha 17, o comando replace realiza a troca do termo “CSHARP” por “C#”. Este
comando pode ser utilizado para substituir um caractere ou uma coleção de caracteres
de uma string. Se você realizar um replace para substituir uma determinada letra, todas
as letras da string serão substituídas.
• Nas linhas 20 e 23, são utilizados os comandos ToUpper e ToLower que alteram todo o
texto para minúsculo e maiúsculo.
• Na linha 26, o comando IndexOf procura a posição da string que está a primeira ocorrência
do caractere “#”. Vale relembrar que, uma variável do tipo string é armazenada em
uma estrutura de vetor (array) de uma dimensão.
• Na linha 29, o comando Substring recortou parte do conteúdo, ou seja, todo o texto a
partir da posição 2 foi recortado e o restante foi descartado.
• Diferente da linha 29, no comando Substring utilizado na linha 32, foi definida a posição
inicial que deve ser recortada a string e quantas posições serão recortadas a partir da
posição inicial.
Você pode concatenar cadeias de caracteres usando o operador + para concatenar literais
de cadeia de caracteres e constantes de cadeia de caracteres. A concatenação de literais
ocorre em tempo de compilação, ou seja, não ocorre nenhuma concatenação de tempo de
execução. Por outro lado, para variáveis de cadeia de caracteres, a concatenação ocorre
somente em tempo de execução (MICROSOFT, 2019).
Perceba que, no exemplo (Figura 12), é utilizada a concatenação para dividir um literal de
cadeia de caracteres ao longo código, em cadeias de caracteres menores, a fim de melhorar
a legibilidade no código-fonte. Essas partes são concatenadas em uma única cadeia de
caracteres em tempo de compilação. Note que, o valor apresentado contém todo o literal
que foi concatenado.
Outro método para concatenar cadeias de caracteres é o String.Format. Esse método funciona
bem quando você está criando uma cadeia de caracteres com base em um pequeno
número de cadeias de caracteres. O exemplo (Figura 15), representa a utilização deste tipo
de concatenação. Note que o valor {0} foi substituído pela data atual, e o valor {1} por Brasil.
saiba mais!
Você acabou de conhecer várias formas de realizar a concatenação. Entretanto, além
dos tipos apresentados nesta aula, existem outros tipos que podem ser visualizados
clicando aqui.
• Nas linhas 13 e 14, são criadas as variáveis que serão utilizadas. A variável valor é tipo
decimal e recebe um número com 3 casas decimais (23.367), perceba que o separador
decimal é o ponto e não a vírgula.
• Na linha 19, ao utilizar {0:C2}, o valor 23.367 é formatado para o valor da moeda corrente
e arredondado para duas casas decimais (23.37). A letra C define que o valor deve ser
formado com símbolo da moeda corrente do sistema operacional, e o número 2 define
a quantidade de casas decimais.
• Na linha 22, ao utilizar o {0:N1}, o valor 23.367 é arredondado para uma casa decimal
(23.4). Se fossem duas casas decimais, a expressão seria {0:N2}.
saiba mais!
Estes foram apenas alguns exemplos do String.Format. Você pode acessar o site da
Microsoft e conhecer outros exemplos de utilização do String.Format. Acesse clicando
aqui.
Antes de começar a explicar sobre DateTime, vamos aprender como este tipo é controlado
e armazenado na memória. Na linguagem C#, uma data e hora é expressada no número de
intervalo de 100 nanossegundos decorridos desde do 1º de janeiro, do ano 0001 em 00:00:00.0000
no calendário gregoriano. Então, cada Tick equivale a 100 nanossegundos. No exemplo (Figura
17), apresenta na tela uma data e seu número em ticks.
Neste momento, você está preocupado(a) e com a seguinte dúvida: será que vou precisar
conhecer como ticks é convertido em data? Claro que não, pois o tipo DataTime possui
métodos que realizam este procedimento para facilitar a nossa vida.
Para criar um objeto do tipo data é possível instanciar uma data utilizando alguns métodos
construtores. O exemplo (Figura 18), apresenta três exemplos de criação de datas. Na variável
data1, adicionamos a data 14/01/2014. Na variável data2, foi adicionado a hora, minutos e
segundos. Na variável data3, foi adicionado os milésimos de segundo.
importante
O Tempo Universal Coordenado (do inglês Universal Time Coordinated) é o fuso horário de
referência, a partir do qual, se calculam todas as outras zonas horárias do mundo. Por exemplo,
note que a data1 é diferente da data3, pois o fuso horário de Brasília possui três horas de
diferença em relação ao horário UTC.
DICA DO AUTOR
Se for desenvolver um software com acesso mundial, seria importante que a data
fosse armazenada e manipulada como UTC. Pois, para descobrir o horário atual,
seria necessário apenas, converter com base no fuso horário.
É possível utilizar outras estruturas disponíveis no objeto DateTime. Por exemplo, é possível
imprimir na tela, apenas parte de uma data. É possível adicionar uma quantidade de dias,
anos ou meses em uma data. O exemplo (Figura 20), representa alguns desses comandos.
LEMBRE-SE!
Até o momento, abordamos conceitos importantes para te auxiliar a
compreender a estrutura e outros conceitos relacionados à linguagem
de programação C#. A partir de agora, vamos iniciar nossos estudos
relacionados à Programação Orientada a Objetos. Claro, utilizando a
linguagem C#, pois você já está preparado(a)!
4. CLASSES E OBJETOS
Até o momento, todos os exemplos foram desenvolvidos apenas com a utilização da classe
program, sem pensar em programação orientada a objetos. Então, chegou o momento tão
esperado! Vamos aprender sobre os conceitos de programação orientada a objetos na prática.
Inicialmente, vamos relembrar o que é classe e objeto para iniciarmos o desenvolvimento dos
nossos primeiros programas em POO.
Você precisa controlar as contas bancárias de uma instituição financeira, então, inicialmente,
você precisa definir o que será armazenado para que seja necessário controlar os dados da
conta bancária.
Vamos lá!!!! Crie um projeto no Visual Studio do tipo Visual C# e Console Application (.Net
Framework), chamado ContaBancaria 1. Em seguida, entre no menu Projeto (Project) e
adicione (Add) uma nova classe. Esta nova classe terá o nome de Conta. A estrutura da classe
é apresentada na Figura 21.
• Entre as linhas 1 e 5, são declaramos os namespaces que podem ser utilizados na classe.
Dentro de cada namespace, pode existir um conjunto de funcionalidades pré-definidas
que podem ser utilizadas pela classe. Na prática, seria uma forma de deixar transparente
o seu uso dentro do contexto. Resumidamente, namespace podem ser consideradas
bibliotecas com estruturas pré-definidas.
• Na linha 7, é definido o namespace da classe Conta. Isto seria uma forma de organizar
as classes que pertencem a um mesmo domínio. Por exemplo, todas as classes que
realizaram o controle de transações bancárias poderiam ter um namespace único com
a declaração namespace Financeiro.
• E por fim, tudo que estiver entre as chaves da linha 10 e 11 fazem parte do escopo da
classe, ou seja, da sua estrutura.
Para controlarmos uma conta bancária, é preciso armazenar e controlar alguns dados, como:
saldo, titular da conta e número da conta. Então, perceba que esses itens podem ser criados
com a utilização de variáveis, que são conhecidas como atributos de classe. O exemplo (Figura
23) representa a criação da classe e seus atributos.
importante
Até o momento, temos duas classes em nosso projeto Conta Bancária. A classe Program que
foi criada automaticamente e será a primeira a ser criada e a classe Conta que criamos. Então,
vamos analisar como uma classe pode se relacionar com outra classe. Lembre-se que foi criada
uma classe e não um objeto. Então, para criar um objeto é necessário criar uma instância da
classe Conta e dar um nome para esta instância (objeto).
• Na linha 13, foi criada uma instância da classe Conta com nome contabancaria, ou seja,
foi criado um objeto da Classe conta com nome contabancaria. Neste momento, você
percebe que uma das formas de criar uma instância de uma classe é: NomeClasse
nomeobjeto = new NomeClasse ();
• Nas linhas 14, 15 e 16, os valores da classe são alterados. Perceba que, para acessar os
valores da classe, foi necessário utilizar o ponto(.). Por exemplo, para acessar e alterar o
saldo, foi necessário colocar a linha de código: contabancaria.saldo = 1500;. Isto é um
conceito importante de Programação Orientada a Objetos, pois para acessar qualquer
estrutura de objeto é necessário utilizar o ponto(.).
! FIQUE ATENTO!
VAMOS PRATICAR?!
Exercício Resolvido 3:
Enquanto as variáveis armazenam dados referentes aos objetos, os métodos podem realizar
operações com essas variáveis ou operações internas.
De forma geral, os métodos podem (ou não) receber valores de entrada que podem ser
opcionais e que são chamados de parâmetros dos métodos. Além disso, em algumas situações
um método pode gerar um valor de saída (retorno) (MANZANO, 2014).
Lembre-se que, utilizar métodos pode tornar o trabalho de desenvolvimento mais versátil, pois:
• é possível dividir uma classe em pequenas partes (métodos) e com características que
possam ser reutilizadas várias partes do programa (MANZANO, 2014);
• pode auxiliar a dividir um problema complexo em pequenas partes, pois, dessa forma,
cada parte menor terá um algoritmo simples (MANZANO,2014).
<corpo>;
• tipo: é o tipo de dado de retorno do método após sua execução. Pode ser o nome de um
tipo primitivo da linguagem como: int, float, double, string, long, byte, entre outros. Se o
método não for retornar valor, deve-se usar a palavra reservada void (MANZANO,2014).
• nome: é o nome com o qual o método será chamado. Como boa prática, você deve
adicionar um nome que ajude a compreender sua finalidade, por exemplo, se for criar
um método para calcular uma soma, seu nome seria CalcularSoma().
• corpo: é o código que executa a ação do método. Note que, em vários exemplos,
implementamos o corpo do Método Main() da classe Program.
• Como o método Main() é o primeiro ser executado, ao passar pela linha 13 o método
• O static nos dois métodos define que método é da classe e não de objeto. Veremos este
conceito com maiores detalhes mais adiante, na disciplina.
O exemplo (Figura 29), possui o mesmo resultado do exemplo apresentado na Figura 28.
Entretanto, neste exemplo, o método retorna o resultado e a responsabilidade de mostrar na
tela é o método Main().
• Na linha 19, ao substituir o void pelo int, define que o método deve retornar um valor um
número inteiro (int).
• Na linha 14, é criada uma variável do tipo int para receber o resultado que for retornado
pelo método CalcularSoma. Note que, nesta mesma linha, é passado como parâmetro
dos métodos CalcularSoma, os valores 10 e 20.
• As Linhas 15 e 16, são responsáveis por mostrar o valor na tela e pausar a tela até que
uma tecla seja pressionada.
Note que, neste exemplo (Figura 29), a responsabilidade de imprimir os valores foi do método
Main(). Além disso, não é necessário utilizar a variável resultado, pois seria possível atribuir o
nome da função na linha 15, conforme o exemplo:
Para utilizar a classe e o método criado no exemplo anterior (Figura 30), é necessário criar um
objeto da classe “Conta” e realizar os passos, conforme o exemplo apresentado na Figura 31.
O exemplo da Figura 31, utiliza a classe Program e o método Main() para criar uma objeto
(instância) da classe Conta e suas características são:
• Na linha 13, é criado uma variável para receber o valor que será depositado.
• Entre as linhas 15 e 17, são armazenados os valores da classe. Note que estes valores
• Nas linhas 20 e 21, é mostrada a mensagem para o usuário inserir o valor do depósito.
VAMOS PRATICAR?!
Parabéns!!! Você já sabe criar classes, instanciar objetos e criar
métodos. Então, para finalizar esta aula e para te auxiliar na Aula
03, a seguir é proposto um exercício relacionado à criação de
métodos. Vamos lá, você consegue!
Exercício Resolvido 4:
Utilizando a estrutura da classe “Conta Bancária”, acrescente um
método para realizar um Saque na conta e simule este saque,
utilizando uma instância da classe conta na classe “Program”.
Entretanto, antes de realizar o saque, verifique se existe saldo
disponível.
CONECTANDO
RECAPITULANDO
Caro(a) Aluno(a), chegamos ao fim da nossa aula. Espero que tenha compreendido o conteúdo
e resolvido os exercícios. Inicialmente, estudamos sobre array e uma miscelânea de estruturas
que são utilizadas na linguagem C#. Em seguida, foi apresentado como classes e objetos são
criados. E por fim, aprendemos a criar métodos (comportamentos) nas classes.
Muito bem! Em nossa próxima Aula, vamos continuar nosso estudo sobre Programação
Orientada a Objetos, com ênfase no desenvolvimento de programas com várias classes,
utilização de herança, properties, encapsulamento e outras estruturas.
VIDEOAULA
Após a leitura e o estudo do seu livro-texto, chegou o momento de
complementar seu conhecimento. Vá até seu Ambiente Virtual
de Aprendizagem e acesse a Videoaula referente à Aula.
Exercício 2:
Exercício 3:
Exercício 4:
DEITEL, H.; DEITEL, P.; STEINBUHLER, K. C# Como Programar. 1. ed. São Paulo: Pearson, 2003.
MANZANO, José Augusto N. G. Programação de computadores C#. São Paulo: Érica, 2014.
SHARP, John; MANIEZ, Dominique. Visual C# 2010. Microsoft Press, 2010. Porto Alegre:
Bookman, 2011.
AULA 4
Objetivos Específicos:
! FIQUE ATENTO!
Boa aula!
ENCAPSULAMENTO E
MODIFICADORES DE
ACESSO
ENCAPSULAMENTO
ACESSO POR
PROPRIEDADES
TODOS OS NÍVEIS DE
ACESSIBILIDADE NA
PROJETOS POO E LINGUAGEM C#
CONCEITOS
MÉTODO CONSTRUTOR
TRABALHANDO COM
HERANÇA
MÉTODOS E CLASSES
ABSTRATAS
PASCAL CASE
CONVENÇÕES DO .NET
Criamos uma classe Conta para controlar o saldo e os dados do titular da conta. Além disso,
implementamos um método para realizar Depósito (Figura 1)
E para simular um depósito utilizando o método Depositar, criamos uma estrutura na classe
Program que recebe como entrada o valor a ser depositado. O exemplo (Figura 2), representa
a classe Program.
Neste momento, você percebe que existe um problema, pois em qualquer parte do software
que tenha acesso a classe Conta será possível acessar e alterar o saldo sem a necessidade de
utilizar o método depositar. Sabe por que isto aconte? Porque o tipo de visibilidade do atributo
da classe Conta é público (public), que permite que qualquer classe possa alterar ou modificar
o seu valor, sem a necessidade da utilização de um método. Contudo, para alterar o saldo,
o correto seria a utilização de um método Depositar (Figura 1) e para diminuir o saldo seria
necessário criar um método Sacar.
Preocupado(a)? Fique tranquilo(a)! Pois este problema pode ser solucionado com a utilização
do encapsulamento que será abordado a seguir.
1.2 ENCAPSULAMENTO
Como estudamos na primeira Aula, o encapsulamento é um dos pilares da programação
orientada a objetos e está relacionado a segurança dos objetos de uma classe. Uma das
aplicações do encapsulamento está relacionada à necessidade de esconder recursos,
protegendo-os ou privando-os em relação ao seu uso. O encapsulamento proporciona
estabelecer o conjunto de recursos que podem ser visíveis ou invisíveis, os quais são definidos
pelos qualificadores básicos public, private e protected.
importante
Vamos voltar ao Projeto de Conta Bancária. Quando liberamos o acesso aos atributos da classe
Conta, foi permitido que qualquer desenvolvedor alterasse os valores utilizando sua própria
regra ou lógica. Mas por segurança, o correto seria a implementação de restrições para que o
valor do saldo fosse alterado somente por meio de métodos. Ao implementar esta regra, seria
possível garantir a integridade dos dados e como resultado, teríamos uma maior segurança na
codificação.
! FIQUE ATENTO!
Conforme o exemplo anterior, foi definido que, para alterar o saldo será necessário utilizar os
métodos da classe, por exemplo, para depositar um valor, seria necessário utilizar o método
Depositar.
Acabamos de resolver um problema, porém, outro problema foi gerado, pois em algumas
situações, precisamos acessar o valor de um atributo de classe. Por exemplo, ao alterar o
atributo Saldo para private, a linha linha 21, no exemplo da Figura 02 não funcionaria, pois o
private define um bloqueio tanto para alterações quanto para leitura. Então, não seria possível
imprimir o valor do saldo.
Felizmente, para solucionar este problema é possível definir métodos Get e Set ou utilizar uma
propriedade, que é uma característica muito utilizada na linguagem C#, para definir níveis de
acesso diferentes, tanto para leitura (get) ou para alteração (set). A seguir, vamos aprender a
utilizar as propriedades da linguagem C# no Projeto Conta.
LEMBRE-SE!
Os métodos também podem ter os atributos de visibilidade public,
private e protected com a mesma finalidade que é aplicado nos
atributos de classe. Além disso, existem outros atributos de visibilidade
que são específicos da linguagem C#.
O exemplo (Figura 3), representa a utilização de propriedades para os atributos de classe nome
e codigocliente. Perceba que no exemplo, o nome é definido como público (public) e como
consequência o get (pegar) e set (atribuir) serão visíveis para qualquer classe externa. Por outro
lado, codigocliente é definido como public, mas existe uma restrição para alterar codigocliente
(private set). Então, somente a própria classe Cliente poderá alterá-lo.
Perceba que este tipo de restrição pode ser importante, pois o código de cadastro do cliente
geralmente é gerado pelo banco. Então, por que deixar que ele seja alterado por uma classe
externa?
No que exemplo da Figura 4, ao tentar atribuir um valor para o codigocliente na classe Program
é reportado um erro (sublinhado vermelho). A mensagem de erro informa que a propriedade
não pode ser usada no contexto porque está configurada para ser inacessível (private).
A partir deste momento, quando definirmos os atributos de classe no diagrama de classe, fique
à vontade para substituir por propriedade.
return quantidade;
this.codigocliente = codigocliente;
Perceba que o método set foi definido como private e isto é equivalente ao que realizamos no
código da Figura 3. Note ainda, que o método set precisa receber um parâmetro.
Voltando na classe Conta, para bloquear a alteração do saldo sem a utilização do método,
precisamos fazer as alterações apresentadas a seguir (Figura 5).
Perceba que na linha 13 (Figura 5), o atributo da classe foi alterado para uma propriedade
e o set foi definido como private. Isto define que o valor não pode ser alterado por classe
externas. Porém, pode ser acessado/lido (get).
Para concretizar o aprendizado sobre Propriedades, vamos criar uma classe Calcular que
terá as seguintes propriedades: valorA, valorB e resultado. Vamos criar um método na classe
Calcular que seja resultado = valorA * Math.Sqrt(valorB), caso o valor de valorA seja maior do
que 50, caso contrário o cálculo deve ser resultado = valorA + Math.Sqrt(valorB). O valor do
resultado não pode ser alterado por classes externas.
A seguir (Figura 6), representa a criação da classe Calcular com a seguinte estrutura:
- Nas linhas 11 e 12 ,foram criadas as propriedades valorA e valorB. Perceba que elas são
públicas (public), tanto para alterar o valor (set) quanto para obter o valor (get).
- Na linha 13, é criado a propriedade resultado. Perceba que, foi definido que, não será possível
uma classe externa alterar o seu valor (private set).
- Entre as linhas 17 e 24, está a estrutura do método, conforme foi definido no exercício.
Mais adiante no texto, vamos discutir sobre a visibilidade protected, utilizada na herança.
Fantástico! Não é verdade? Agora você sabe como utilizar as propriedades, a seguir vamos
analisar outros tipos de visibilidade exclusivos da linguagem C#.
Vale ressaltar que os modificadores de acesso não são permitidos em namespaces, pois,
namespaces não possuem nenhuma restrição de acesso. Além disso, dependendo do contexto
no qual ocorre uma declaração de membro, apenas algumas acessibilidades declaradas são
permitidas.
Você deve estar pensando: como posso utilizar todos os modificadores de acessibilidade?
Fique tranquilo, pois já abordamos os principais (private e public) e teremos mais exemplos
adiante na disciplina.
DICA DO AUTOR
Para conhecer mais detalhes sobre os modificadores na linguagem C#, clique
aqui.
Parabéns, agora você consegue criar propriedades em classe! Mas você sabe explicar a
diferença básica entre um atributo de classe e uma propriedade em relação a visibilidade?
No atributo de classe, quando definimos que ele é private, ele fica bloqueado tanto para
leitura ou para escrita. Já na propriedade, é possível definir caminhos distintos para leitura (get)
e escrita (set). Resumidamente, no atributo definimos apenas um caminho, tanto para leitura
quanto para a escrita. Por outro lado, na propriedade é possível definir tipos de visibilidade
distintas para leitura (get) e escrita (set).
O exemplo da Figura 7, representa uma classe com dois métodos construtores. Perceba que
os dois métodos não possuem tipo (int, void, float), porém, todo método construtor não retorna
nenhum valor. O primeiro método construtor (linha 12 a 15) é o padrão que será executado,
caso outro método não seja executado. O segundo método, é um construtor que, para ser
executado, precisa receber como parâmetro um valor do tipo inteiro.
! FIQUE ATENTO!
No exemplo da Figura 8, é criada uma instância da ClasseA (Figura 7), em seguida, o segundo
método construtor ClasseA(int A) é utilizado. Perceba que ao instanciar, foi passado como
parâmetro o valor 20, o cálculo A + 20 foi executado e o resultado apresentado na tela. Note
que, se não fosse passado parâmetro, o primeiro método construtor seria executado.
Para concretizar o aprendizado sobre método construtor, vamos criar um projeto que tenha
uma classe Circunferencia para realizar o cálculo da área. Nesta classe, vamos criar dois
métodos construtores, o primeiro será padrão, ou seja, sem parâmetros, o segundo terá como
parâmetro o valor do radiano.
No exemplo da Figura 9, temos dois métodos construtores. Então, vamos analisar o código:
- Na linha 11, foi criado o atributo de classe para armazenar o valor do radiano, perceba que
não utilizamos propriedade e o atributo é do tipo private, ou seja, somente a própria classe terá
acesso ao valor.
- Entre as linhas 16 e 19, está a estrutura do segundo método construtor. Perceba que utilizamos
um novo conceito. Como o parâmetro do método possui o mesmo nome do atributo de classe,
foi utilizado o termo this, que define que a variável é um atributo de classe e não o parâmetro.
- Entre as linhas 20 e 23, é definida a estrutura do método CalcularArea. Note que este método
retorna um tipo double.
O exemplo da Figura 10, cria uma instância da classe Circunferencia e executa um exemplo
de cálculo da área:
- Na linha 13, foi criado um tipo Cincunferencia. Note que neste momento, ainda não foi
criado uma instância.
- A Linha 15, executa e imprime o valor do cálculo da área na tela. Perceba que foi
utilizado o nome do objeto mais o nome do método (c.Area()). Isto é possível, pois o
método CalcualarArea retorna um valor do tipo double.
No mercado se você perguntar para alguns desenvolvedores experientes sobre o que eles
entendem sobre herança, em geral, você terá respostas diferentes e contraditórias, o que
de fato é compreensível, pois a própria palavra herança tem vários significados sutilmente
diferentes. Por exemplo, se uma pessoa deixar uma herança para você, é correto dizer que
você herdou. Da mesma forma, você herda metade dos seus genes da sua mãe e a outra
metade do seu pai (SHARP, 2010).
! FIQUE ATENTO!
- Os dois atributos area e perimetro podem ser alterados apenas pela própria classe ou
pelas duas classes filhas (Quadrado e Circunferencia).
- Perceba que existem dois métodos na classe Quadrado e Circunferencia que definem
que os métodos irão sobrepor o método da classe Forma.
- Note que a classe Quadrado possui o atributo lado que é exclusivo dela, pois para
realizar o cálculo da área e do perímetro, será necessário informar este valor. Por outro
lado, a classe Circunferencia possui o atributo radiano que precisa ser informado para
realizar os mesmos cálculos.
- Os atributos area e perimetro que são utilizados para armazenar os resultados dos cálculos,
são do tipo protected que no diagrama de classe é representada pelo símbolo #. Isto
define que eles podem ser alterados pela própria classe e pelas classe filhas (subclasses).
- O restante dos atributos e métodos são do tipo public (+), ou seja, podem ser acessados
e alterados por classes externas.
- Perceba que o nome da classe Forma está em itálico. Isto significa que a classe é do
tipo abstrata. Uma classe abstrata não pode ser instanciada. Então, se analisarmos com
cuidado, deixar a classe Forma como abstrata seria importante e coerente, pois sempre
que for necessário realizar um cálculo é necessário instanciar a classe especialista
(subclasse) e não a classe generalista (superclasse).
O exemplo da Figura 12, representa a criação da classe Forma. Note que, existem as
seguintes características e conceitos:
- Na linha 9, o termo abstract define que a classe é abstrata. Uma classe abstrata não
pode ser instanciada por outras classes. Mais adiante, teremos um conteúdo exclusivo
para classe e métodos abstratos.
- Nas linhas 11 e 12, foram criadas propriedades como alternativa aos atributos de classe.
Note que, estes atributos são públicos para leitura (get) e protected para alteração (set),
ou seja, somente a classe e as classe filhas podem alterar o valor da area e perimetro.
- Nas linhas 14 e 15, foram criadas apenas as assinaturas dos métodos. Além disso, foi
adicionado um novo conceito, pois quando adicionamos o termo virtual antes do
void, deixamos claro que o método pode ser sobreposto pelas subclasses (Quadrado
e Circunferencia). Neste momento, você percebe que existe uma coerência, pois
cada tipo de forma geométrica possui um cálculo diferente para descobrir a área e o
perímetro. Então, quem será responsável por implementar os cálculos serão as classes
Quadrado e Circunferencia.
- Note que na linha 9, foi adicionado após o nome da classe o seguinte código : Forma.
isto declara que a classe Circunferencia é filha (subclasse) da classe Forma. Então, a
partir dessa declaração tudo que for public ou protected da classe Forma será herdado
pela classe Circunferencia.
- Note que na linha 13, ao criar o método CalcularArea(), foi adicionado o termo override,
este termo define que o método vai sobrepor o método da superclasse Forma. Atenção:
Neste momento, estamos aplicando o conceito de polimorfismo que é um dos pilares da
programação orientada a objeto.
- Na linha 15, é implementado o cálculo da área. Você deve estar pensando: onde foi
criado o atributo de classe ou propriedade com nome area na classe Circunferencia?
Neste momento, notamos a aplicação da herança, pois a propriedade area está na
classe Forma e foi herdado pela classe Circunferencia. Mas porquê? Porque qualquer
forma geométrica possui uma área.
LEMBRE-SE!
Polimorfismo é a capacidade de que métodos de classe que
possuem um relacionamento de herança com outra classe possam
ter comportamento com características próprias.
- Na linha 9, é criada a classe Quadrado que como herança da classe Forma (: Forma).
Agora vamos implementar uma estrutura na classe Program para realizar o cálculo da área e
perímetro da Circunferência.
- Na Linha 18, os valores dos perímetro e área são apresentados na tela. Note que os
valores foram arredondados para duas casas decimais (N2).
VAMOS PRATICAR?!
Exercício Resolvido 01 - Utilizando o exemplo de cálculo de formas
geométricas, realize as alterações conforme descrito e o diagrama
de classe disponível a seguir:
• Adicionar a classe Triangulo que herda da classe Forma.
• Implementar o método CalcularArea() de acordo com o tipo
do triângulo.
• O método TipoTriangulo() deve retornar se o triângulo é
Isósceles, equilátero ou escaleno.
• A classe Program deve ter uma opção para o usuário escolher
qual a Forma ele deseja calcular (Dica: utilizar o if)
importante
Lembra da nossa classe conta? Se não lembra, volte no início da aula e analise sua estrutura.
Imagine um ambiente bancário onde as contas possam ter atributos e forma de realizar o
saque e depósito distintas. Por exemplo, em uma conta corrente, para analisar se existe o saldo,
seria necessário um atributo para controlar o valor do cheque especial. Ao analisar se existe
saldo para realizar um saque, seria necessário considerar o valor do cheque especial. Por outro
lado, em uma conta poupança não existe cheque especial. Neste momento, percebemos
que uma alternativa seria a utilização de herança. Então, vamos transformar a classe Conta
em três classes: Conta, Corrente e Poupança. Primeiro, vamos alterar a classe Conta, conforme
exemplo apresentado a seguir.
- O set (Alteração) da propriedade saldo foi alterado para protected, pois apenas a própria
classe e as classes filhas (Poupanca e Corrente) podem alterar o valor do saldo.
- Como o método depositar é idêntico para todas as classes, sua estrutura foi implementada
na classe Conta.
O exemplo da Figura 18 representa a classe Corrente. Note que, a classe herda da classe
Conta (Corrente : Conta). Além disso, foi adicionado uma propriedade para controlar o cheque
especial. E no Método Sacar, para realizar o saque o valor precisa ser maior do que a soma do
saldo mais o cheque especial.
O exemplo da Figura 19, representa a classe Poupanca. Note que a classe herda da classe
Para finalizar o aprendizado sobre herança, vamos analisar algumas vantagens. Ao analisar
as classes Conta, Poupanca e Corrente perceba que, foram criadas as classes especialistas
(Poupanca e Corrente). No futuro, se for necessário, adicionar uma classe para conta salário,
seria necessário criar uma nova classe sem alterar a estrutura atual. Então, imagine que o
programa já esteja em produção (instalado na empresa), se você adicionar uma nova classe,
sem precisar alterar o código da estrutura que já foi testada e está sendo utilizada pelo usuário,
você pode garantir, com certo grau de certeza que, as funcionalidades já testadas das classes
Poupanca, Conta e Corrente não serão alteradas. Então, é possível afirmar que a herança
pode auxiliar na manutenabilidade, testabilidade e reusabilidade.
importante
CONECTANDO
Lembre-se, que as classes abstratas geralmente possuem métodos abstratos que serão
implementados por classes filhas. Mas em C# pode existir uma classe abstrata sem que os
métodos sejam abstratos. E quando você definir que um método será abstrato a subclasse
deverá, obrigatoriamente, possuir este método. Ops! Já estava esquecendo. Uma classe
abstrata não pode ser instanciada.
Sobre os métodos, você concorda que, para toda forma geométrica, existe uma forma de
calcular o perímetro e área. Então, ao criar uma superclasse abstrata com métodos abstratos
você define uma regra. Pois, toda classe que herdar dessa classe deve obrigatoriamente
declarar os métodos abstratos. Mas lembre-se, declarar é diferente de implementar, e isto
significa que a subclasse pode apenas declarar a estrutura do método sem implementá-lo.
O exemplo da Figura 20, representa a alteração da classe Forma para abstrata. Além disso,
alguns métodos foram transformados em abstratos:
- Na linha 16, criamos um método CalcularCor que é virtual e pode ou não, ser utilizado
pelas subclasses;
O exemplo da Figura 21, representa a classe Quadrado que herda da classe Forma (abstrata).
Note que, não foi criado/sobreposto o método CalculcarPerimetro. Neste exemplo, a IDE
(Visual Studio) mostra que existe um erro, pois é obrigatório que todos os métodos abstratos
sejam declarados.
importante
Então, para resolver este problema, basta criarmos uma classe Cliente, onde tudo que pertencer
ao cliente será adicionado nesta classe. O exemplo da Figura 22, representa a classe Cliente
com duas propriedades.
Como criamos uma classe Cliente, então será necessário alterar a classe Conta. Note que, no
exemplo da Figura 23, o atributo de classe nome foi substituído por uma instância da classe
Cliente.
Para acessar o nome do cliente, a partir deste momento, será necessário acessar o objeto
cliente que está agregado à classe conta. O exemplo a seguir, representa este acesso.
Perceba que, para acessar e armazenar o nome do cliente foi acessado o objeto contabancaria
que possui o objeto cliente. (contabancaria.cliente.nome). Além disso, se você quiser detalhar
ainda mais, seria possível criar uma classe Endereco que estaria agregada na classe Cliente,
que em seguida, estaria agregada na classe Conta.
Mas antes de abordar sobre convenções, vamos analisar um pouco da história. Nas décadas
de 1970 e 1980, começou a ser adotada uma prática de escrita utilizando uma convenção de
nomeação padrão ou alternativa para identificadores em várias linguagens de programação.
A origem desta convenção na programação de computadores não é precisa. Entretanto, a
utilização desta técnica é recomendada pelas diretrizes de estilo de codificação de muitas
organizações ou projeto de software (KITAMURA,2019)
- Criam uma aparência consistente para o código, para que os leitores possam se
concentrar no conteúdo e não no layout.
- Permitem que os leitores entendam o código com mais rapidez, fazendo suposições
com base na experiência anterior.
Como são várias as convenções utilizadas pela Microsoft, sugiro que acesse o material oficial.
VAMOS PRATICAR?!
Exercícios Resolvido 02 - Um software possui 3 classes: ClasseA,
ClasseB, ClasseC. Utilizando a linguagem orientada a objetos C#
com projeto Console, desenvolva as características descritas a
seguir:
2A– A classeA possui uma propriedade com nome Resultado,
que pode ser alterado apenas pelas classes filhas, mas pode
ser visualizado por outras classes. Nesta mesma classe, existe um
método com nome Calcular():void que será implementado nas
classes filhas. Além disso, essa classe será abstrata.
2B– A classeB herda da ClasseA. Entretanto ela possui três atributos
ou propriedades de classe X, Y e Z. Nesta mesma classe o método
Calcular():void da ClasseA deve ser sobreposto com a seguinte
equação: Resultado = X + Y * 2. Entretanto se o valor de Z for maior
do que 50, o cálculo será Resultado = X + Z * 2.
2C – A classeC herda da classeA, onde o método Calculo():void
da ClasseA deve ser sobreposto com a equação: Resultado = A/B
+ Math.Sqt(Y). Crie os atributos de classe A e B. Cuidado, caso o
valor de B seja igual a zero o resultado deve ser igual a 0.
2D – Na classeC deve ter os atributos nome, telefone.
2E – Crie uma Estrutura na classe Program para realizar o cálculo
da classe A ou B.
2F – Resumidamente, explique(comente no código) onde e quais
conceitos de POO foram utilizados nas classes criadas.
FOLHA DE RESPOSTAS: Os exercícios resolvidos estão disponíveis
na pasta da aula 04
RECAPITULANDO
Caro(a) Aluno(a), chegamos ao fim da nossa Aula. Espero que tenha compreendido o
conteúdo e resolvido os exercícios. Inicialmente, estudamos os conceitos de encapsulamento
e sua implementação no código, em especial, utilizamos as propriedades da linguagem C#.
Abordamos os conceitos de herança e implementamos alguns exemplos. Por fim, foram criados
exemplos de método construtor, polimorfismo e outros conceitos que fazem parte a linguagem
de programação orientada a objetos.
Muito bem! Em nossa próxima Aula, vamos continuar nosso estudo sobre Programação
Orientada a Objetos, com ênfase no desenvolvimento de programas com várias classes,
utilização de herança, propriedades, encapsulamento e outras estruturas.
VIDEOAULA
Após a leitura e o estudo do seu livro-texto, chegou o momento de
complementar seu conhecimento. Vá até seu Ambiente Virtual
de Aprendizagem e acesse a Videoaula referente à Aula.
DEITEL, H.; DEITEL, P.; STEINBUHLER, K. C# Como Programar. 1. ed. São Paulo: Pearson, 2003.
KITAMURA, CELSO. Pascal Case e Camel Case O que é e como usar. Disponível em: https://
celsokitamura.com.br. Acesso em: 01 de Mai. 2019.
MANZANO, José Augusto N. G. Programação de computadores C#. São Paulo: Érica, 2014.
SHARP, John; MANIEZ, Dominique. Visual C# 2010. Microsoft Press, 2010. Porto Alegre:
Bookman, 2011.
AULA 5
Objetivos Específicos:
! FIQUE ATENTO!
Boa aula!
DESENVOLVENDO SOFTWARE
ORIENTADO A OBJETOS - PARTE III
OBJETO DE CLASSE
COMO PARÂMETRO
MÉTODO E CLASSE
ESTÁTICA
ENUMERADORES E
ESTRUTURAS
EXEMPLOS PRÁTICOS DE
UTILIZAÇÃO DE LISTAS
LISTA GENÉRICA
CRIANDO LISTA DE
OBJETOS DE CLASSES
INTERFACE
PASCAL CASE
ORGANIZANDO MEU
CAMEL CASE
CÓDIGO
CONVENÇÕES DO .NET
LEMBRE-SE!
Mas você lembra o conceito de método? Vamos relembrar: método
pode ser definido como um trecho de código independente de
qualquer parte da classe, porém relacionado as funcionalidades
propostas dentro do programa. Ou seja, os métodos são um conjunto
de instruções que efetuam uma tarefa específica. De forma geral, os
métodos podem (ou não) receber valores de entrada que podem ser
opcionais e que são chamados de parâmetros dos métodos. Além
disso, em algumas situações, um método pode gerar um valor de
saída (retorno) (SHARP, 2010).
Então vamos lá! Geralmente, quando você passa um argumento para um método, o parâmetro
correspondente é inicializado com uma cópia do valor. Isso é verdade independente do
parâmetro ser um tipo-valor (como int), um tipo nullable (como int?) ou um tipo-referência.
Então, esta estrutura indica que é impossível que qualquer alteração no parâmetro afete o
valor do argumento passado (SHARP, 2010). Por exemplo, a Figura 1 possui uma um método
que recebe um valor e realiza o incremento do parâmetro (Linhas 19 e 21).
! FIQUE ATENTO!
Perceba que no exemplo da Figura 1, ao incrementar o valor que foi recebido no método
(parametroA++), o valor da variável valorA não foi alterado, pois ao passar o valor para o
parâmetro é realizado uma cópia dos dados. Contudo, talvez em algumas situações seja
necessário que, ao modificar o parâmetro, a variável original seja alterada. Para realizar este
procedimento é possível utilizar os parâmetros com o termo ref. Ou seja, se você utilizar ref,
o parâmetro torna-se um alias do argumento real, ao invés de uma cópia do argumento.
Resumidamente, o parâmetro terá o endereço da memória onde está armazenado o valor
da variável valorA. Ao alterar o parâmetro, o conteúdo do valor original, será alterado. Vale
ressaltar que, na computação a passagem de valor utilizando o ref é chamado de passagem
por referência.
DICA DO AUTOR
Se não lembra como funciona a passagem por referência, consulte a Aula 02.
No exemplo da Figura 2, foi adicionado o termo ref antes de passar o valor como parâmetro (Linha
14) e no parâmetro do método (Linha 19). Ao incrementar o valor do parâmetro parametroA o
valor da variável valorA é alterado, pois ao imprimir a variável valorA é apresentado o valor 51,
diferente do exemplo da Figura 1, que foi criado sem o ref.
saiba mais!
Para saber mais detalhes sobre passagem de valor por referência assista um vídeo,
clicando aqui.
Outra forma de passagem de parâmetro seria a utilização do out que é semelhante a palavra
ref. Porém, quando utilizamos o out, informados que o parâmetro é do tipo output (saída), ou
seja, o valor final do parâmetro será retornado.
A Figura 3, representa um exemplo do out. Perceba que utilizamos o termo out ao passar o
valor para o parâmetro (Linha 14) e na declaração do parâmetro (Linha 19). Ao passar um
argumento com identificador out, o método deve obrigatoriamente atribuir um valor para o
parâmetro. Por exemplo, se retiramos a Linha 21, teremos um erro no código.
Então, antes de falar sobre array como parâmetro, vamos discutir e relembrar sobre sobrecargas
de métodos.
DICA DO AUTOR
Se você não lembra o que é uma array dimensional (vetor) e multidimensional
(matriz), leia a Aula 03.
O exemplo a seguir representa a estrutura de sobrecarga, que são métodos que possuem o
mesmo nome, porém com quantidade de parâmetros ou tipos de dados diferentes.
Perceba que, no exemplo anterior, os métodos possuem o mesmo nome, mas com assinaturas
diferentes. Então, ao utilizar o exemplo a seguir, o primeiro método será executado, pois o valor
que foi passado como argumento e do tipo int.
Embora seja útil, a sobrecarga não cobre todos os casos. Particularmente, a sobrecarga não
trata uma situação em que o tipo dos parâmetros não varia, mas o número de parâmetros
sim. Se você quisesse realizar a soma de vinte valores, você teria que criar uma quantidade
expressiva de métodos, não é verdade?
Felizmente com a utilização de array, listas ou com tipo params, como parâmetro, é possível
escrever um método para receber um número de argumentos variável.
• Nas Linhas 13 e 14, foram criados dois vetores com 5 e 3 elementos. Note que foram
atribuídos valores para todas as posições dos dois vetores.
• Na Linha 19, foi criado um método que recebe como parâmetro um array. O que define
a utilização do array como parâmetro é utilização dos colchetes [ ].
• O método foi invocado duas vezes, nas linhas 15 e 16. Neste momento você pode
analisar a vantagem de utilizar esta estrutura. Note que o método foi capaz de somar
arrays com tamanhos diferentes.
No exemplo a seguir, seria criada uma classe com nome Imprimir que possui um método que
recebe como parâmetros o código e o nome. Em seguida, os dados são apresentados na tela.
No exemplo a seguir é criado instância das classes Cliente e Imprimir. Em seguida é passado
como parâmetros o código e o nome do cliente que estão armazenados no objeto da classe
cliente.
Felizmente, para solucionar este problema, é possível passar como parâmetro o objeto da
classe. A seguir, temos a modificação do método da classe Imprimir. Note que para o método
funcionar ele precisa receber como parâmetro um objeto do tipo Cliente. No corpo do método,
o parâmetro que é um objeto do tipo Cliente é utilizado para imprimir os valores na tela.
Esta estrutura representa o objeto da classe Cliente como parâmetro do método. O interessante
é que a passagem de objeto de classe como argumento, utiliza a passagem por referência
(ref), ou seja, não é realizado uma cópia dos dados do objeto.
VAMOS PRATICAR?!
Exercício Resolvido 1:
Crie uma classe com nome Calcular que contenha os seguintes
métodos e estruturas:
• Criar um método para receber como parâmetro o um array e
calcular a média aritmética dos valores.
• O usuário poderá digitar o tamanho do array que deseja
calcular e digitar os seus valores. Em seguida os valores serão
calculados pelo método da classe Calcular.
Em vários exemplos utilizamos alguns métodos estáticos, por exemplo, na Figura 3, utilizamos o
método estático Main e Somar. Mas o que significa um método estático? Métodos estáticos
não requerem uma instância da classe e não podem acessar de forma implícita os dados. Na
linguagem C# o método estático é definido com o termo static no início da declaração. Além
disso, na Programação Orientada a Objetos, um método estático é considerado um método
da classe e não do objeto. Mas o que significa isto? Isto indica que não é preciso criar um
objeto (instância da classe) para utilizar o método. Vamos analisar um exemplo logo a seguir.
Até o momento, você aprendeu que, para utilizar um método de uma classe seria necessário
criar uma instância (objeto) da classe. Mas com a utilização de métodos estáticos isto não é
necessário. Vamos analisar a diferença entre os dois tipos de métodos: estáticos e não estáticos.
Note a seguir que, para acessar o método calcular, foi necessário criar uma instância da classe
Calcular para utilizar o método e escrever o resultado na tela.
A seguir temos o exemplo da utilização da classe e método estático que foram criados no
exemplo anterior. Note que foi adicionado o nome da classe com a invocação do seu método,
sem a necessidade de criar uma instância da classe.
Interessante não é verdade? Mas qual a utilidade de classes e métodos estáticos? Imagine
em um programa que você utiliza vários cálculos, por exemplo, cálculos de juros e regras de
negócio. Neste momento você pode criar uma classe estática com todos os cálculos e utilizar
em qualquer parte do programa, sem a necessidade de criar instâncias das classes. Muito mais
prático, concorda?
A seguir, vamos analisar outros exemplos para concretizar o seu aprendizado sobre métodos
estáticos.
Note que no exemplo da Figura 6, foi criada uma estrutura para receber os valores do capital,
juro mensal e quantidade de parcelas. Na Linha 25, para utilizar o método JuroComposto da
classe Calculo, não foi necessário criar uma instância da classe, pois o método é estático.
Ainda neste exemplo, foi utilizado outro método estático, pois utilizar o Math.Pow, não foi
necessário instanciar um objeto da classe Math, pois a classe e os métodos pertencentes a ela
são estáticos.
! FIQUE ATENTO!
VAMOS PRATICAR?!
Exercício resolvido 2:
Utilizando mesmo exemplo apresentado sobre método e classe
estática. Crie um segundo método para calcular os juros simples.
Altere a classe programa solicitando que tipo de cálculo deseja
realizar. Lembre-se que o método deve ser estático e altere a
classe para que seja estática.
• Perceba que antes do nome da classe (Linha 9) foi criado um enum com nome
diaSemana e entre os colchetes foram definidos os valores que este enum pode assumir.
• Na Linha 14, é realizada uma análise se o valor passado como parâmetro é Domingo.
O exemplo da Figura 8 mostra a utilização do enum do objeto dia que é do tipo da classe
AnalisarDia. Perceba que na Linha 14, foi passado como parâmetro o termo domingo. Outra
vantagem de utilizar o enum está na definição de um intervalo válido que pode ser passado
! FIQUE ATENTO!
VAMOS PRATICAR?!
Exercício Resolvido 3:
Criar um programa que tenha uma classe com nome Ano. Crie
um enumerador que tenha os meses do ano. Em seguida, crie
um método que receberá como parâmetro um enumerador dos
meses do ano. Esse método deve imprimir na tela qual trimestre
que o mês pertence.
4 - LISTA GENÉRICA
Trabalhar com coleções de dados é uma necessidade comum no desenvolvimento de
programas orientado a objetos. Até o momento você aprendeu a trabalhar com coleções
utilizando array. Entretanto, a utilização do array possui algumas desvantagens, como
ausência de alguns métodos para auxiliar na manipulação dos elementos e principalmente a
necessidade de determinar a quantidade dos elementos antes de começar a utilizá-los.
A seguir vamos analisar como declaramos uma lista. Perceba que foram criadas três listas e
foram definidos os tipos de dados de cada uma. No primeiro exemplo, é criada uma lista de
objetos do tipo string. Na segunda, declaração criamos uma lista de objetos do tipo double e
foi delimitado a quantidade de elementos que podem ser armazenados na lista, representado
pelo número 32. Na última declaração foi criada uma lista de int e adicionado três valores.
Para você aprender como percorrer uma lista, tanto para adicionar ou para imprimir, a seguir
vamos analisar um exemplo.
• Na Linha 13, é criada uma lista de valores do tipo int com nome valores.
• Entre as Linhas 14 e 17, está a estrutura repetitiva utilizando o for. Nessa estrutura é
adicionada os valores na lista. Perceba que na Linha 16, a cada repetição o valor de i
é adicionado na lista.
• Entre as Linhas 19 e 22, é realizada a impressão dos valores da lista na tela. Neste momento
é utilizado o comando de repetição foreach, que não abordamos até o momento. A
estrutura de repetição do foreach percorre uma coleção de dados automaticamente.
A cada repetição a “variável” item terá o valor de um item da lista, por exemplo, na
primeira execução (Linha 21), o item terá o valor 1, na segunda o valor 2, e assim por
diante, até percorrer toda lista. Além disso, no lugar do termo var, seria possível adicionar
int, pois os valores da lista do exemplo pertencem a este tipo
Para exemplificar a utilização de alguns métodos da lista, a seguir vamos analisar como
adicionar e remover itens da lista.
Perceba que, no exemplo da Figura 10, na Linha 18 foi utilizado o método Remove, e passado
como parâmetro valor 1. Então, o primeiro valor da lista foi removido. Na linha 19, foi utilizado o
método RemoveAll para remover todos os elementos da lista maiores do que 5, neste exemplo
utilizamos lambda.
Você deve estar pensando: o que é lambda? Fique tranquilo, pois este conteúdo será abordado
mais adiante na disciplina.
Vamos analisar outro exemplo! O exemplo do diagrama de classe a seguir (Figura 11),
representa o relacionamento de composição entre as classes Cliente e Telefone. Neste exemplo
foi definido que um cliente é composto por telefones e não pode existir sem que exista pelo
menos um telefone.
A seguir vamos implementar o código da Figura 11. Preste atenção nos detalhes!
O código da Figura 12, representa a classe Telefone. Note que a classe não possui métodos.
O código a seguir (Figura 13), representa a classe Cliente. Note que ela possui propriedades,
atributos de classe e métodos.
A estrutura do código da classe Cliente (Figura 13), pode ser detalhada como:
• A Linha 13, contém a declaração de um atributo de classe que representa uma lista do
tipo da classe Telefone. Esta declaração representa a composição que foi definida no
diagrama de classe (Figura 11).
A estrutura do código da classe Program (Figura 14), pode ser detalhada como:
• Perceba que são adicionados dois telefones, conforme a quantidade de iterações que
foram definidas no for.
VAMOS PRATICAR?!
Exercício Resolvido 4:
Crie um controle para armazenar os dados de Funcionários e
Dependentes. Utilize a lista para armazenar os dependentes
dentro da classe Funcionário, além disso, mostre na tela todos os
dependentes do funcionário.
5 - INTERFACE
É possível definir como interface o contrato entre as classes e o mundo exterior. Quando uma
classe implementa uma interface, se compromete em fornecer o comportamento publicada
por esta interface. Uma interface contém definições para um grupo de funcionalidades
relacionadas, que uma classe ou um struct pode implementar. Por outro lado, utilizando
interfaces, você pode, por exemplo, incluir o comportamento de várias fontes em uma classe.
Essa funcionalidade é importante em C#, pois a linguagem não dá suporte a herança em
mais de uma classe, ou seja, herança múltipla. Além disso, utilize uma interface se você deseja
simular a herança para structs, pois eles não podem herdar de outro struct ou classe.
Você define uma interface utilizando a palavra-chave interface no lugar da palavra chave
class, como mostrado no exemplo a seguir. E geralmente por convenção e boas práticas é
utilizado a letra maiúscula I no início do nome da interface (MICROSOFT, 2019).
! FIQUE ATENTO!
Note que, no exemplo (Figura 15), foi implementada uma interface com nome IConta. O
diagrama representado pelo estereótipo <<interface>>, informa que é uma interface. Uma
interface não pode ter atributos de classe, mas como já comentamos anteriormente, em alguns
exemplos vamos implementar como propriedades alguns atributos de classe de determinados
diagramas. Neste caso foi realizado este procedimento, conforme o código do exemplo. Note
também, que foram declaradas apenas as assinaturas dos métodos, pois a responsabilidade
de implementar os métodos será da classe que assinar um contrato (implementar) com a
interface.
Agora vamos analisar como seria uma a assinatura (implementação) de duas classes com a
interface IConta. O diagrama da Figura 16, mostra que existem duas classes Corrente e Conta
que implementam a interface IConta.
O código a seguir (Figura 17) representa a classe Corrente que implementa a interface
IConta.
• Na Linha 9, a assinatura com a interface IConta é definida. Veja que a forma de identificar
uma interface é a mesma utilizada na definição de herança, ou seja, com a utilização
de dois pontos e o nome da interface que será implementada pela classe.
• Foi criado um método com nome CalcularTarifa que não existe na interface IConta. Isto
indica que, a classe pode ter propriedades e métodos que não existem na interface que
foi implementada.
O exemplo da Figura 18, representa a classe Poupanca implementando a interface. Note que
não existe diferença com a classe Corrente, exceto no método CalcularTaxa que não foi criado
na classe Poupanca.
• Na Linha 13, foi criado um tipo IConta com nome conta. Perceba que a classe não
foi instanciada neste momento. E neste momento, percebemos uma das vantagens
de utilizar interfaces. Pois em tempo de execução, conta pode se tornar uma conta
corrente ou poupança.
• Após definido o tipo de conta que deseja manipular, na linha 20 ou 23 é criada uma
instância da classe Corrente ou Poupanca.
VAMOS PRATICAR?!
Exercício Resolvido 5:
Utilizando o mesmo exemplo apresentado sobre Interface, crie
uma classe salario que implementa a interface IConta. Adicionar
na classe program a opção 3 para manipular o depósito e saldo
na neste tipo de conta.
Mas antes de abordar sobre convenções, vamos analisar um pouco da história. Nas décadas
de 1970 e 1980, começou a ser adotada uma prática de escrita utilizando uma convenção de
nomeação padrão ou alternativa para identificadores em várias linguagens de programação.
A origem precisa desta convenção na programação de computadores não é precisa.
Entretanto, a utilização dessa técnica é recomendada pelas diretrizes de estilo de codificação
de muitas organizações ou projeto de software (KITAMURA, 2019)
• Criam uma aparência consistente para o código, para que os leitores possam se
concentrar no conteúdo e não no layout.
• Permitem que os leitores entendam o código com mais rapidez, fazendo suposições
com base na experiência anterior.
Como são várias as convenções utilizadas pela Microsoft, sugiro que acesse o material oficial.
saiba mais!
A partir das próximas aulas vamos utilizar o Pascal Case e o Camel Case para definir
o nome dos objetos. Também iremos utilizar algumas convenções da Microsoft. Leia a
documentação da Microsoft sobre convenções da linguagem C# na íntegra. Basta
clicar aqui.
aUTOaVALIAÇÃO
Após essa aula, você é capaz de desenvolver e aplicar os conceitos de
lista genérica? É capaz de desenvolver e aplicar os conceitos de métodos
estáticos? Consegue desenvolver enum para organizar o código? Caso
você consiga responder estas questões, parabéns! Você atingiu os objetivos
específicos da Aula 5! Caso tenha dificuldades para responder alguma(s)
dela(s), aproveite para reler o conteúdo da Aula, acessar o UNIARAXÁ Virtual
e interagir com seus colegas e com o(a) tutor(a) e esclarecer todas as suas
dúvidas. Você não está sozinho nessa caminhada! Conte conosco!
RECAPITULANDO
Caro(a) Aluno(a), chegamos ao fim da nossa aula. Espero que tenha compreendido o conteúdo
e resolvido os exercícios. Estudamos sobre tipos de parâmetros dos métodos, classes e métodos
estáticos, implementação de listas e interfaces utilizando a linguagem C#.
Muito bem! Em nossa próxima Aula, vamos continuar nosso estudo sobre Programação Orientada
a Objetos, com ênfase no desenvolvimento de programas com utilização de Lambda e Linq,
conteúdo amplamente utilizado em projetos na linguagem C#.
VIDEOAULA
Após a leitura e o estudo do seu livro-texto, chegou o momento de
complementar seu conhecimento. Vá até seu Ambiente Virtual
de Aprendizagem e acesse a Videoaula referente à Aula.
DEITEL, H.; DEITEL, P.; STEINBUHLER, K. C# Como Programar. 1. ed. São Paulo: Pearson, 2003.
KITAMURA, CELSO. Pascal Case e Camel Case, O que é e como usar. Disponível em: <https://
celsokitamura.com.br>. Acesso em 01 de jul. de 2019.
MANZANO, José Augusto N. G. Programação de computadores C#. São Paulo: Érica, 2014.
SHARP, John; MANIEZ, Dominique. Visual C# 2010. Microsoft Press, 2010. Porto Alegre:
Bookman, 2011.
AULA 6
Objetivos Específicos:
No final desta Aula, você será capaz de trabalhar com pesquisa utilizando LINQ e outros
conceitos avançados de Programação Orientada a Objetos. Você sabe trabalhar com
expressões lambda? Sabe o que significa tratamento de exceção? Sabe criar delegates?
Nessa aula, você terá as respostas para essas e outras perguntas.
! FIQUE ATENTO!
Boa aula!
DESENVOLVENDO SOFTWARE
ORIENTADO A OBJETOS - PARTE IV
TRABALHANDO COM
ARQUIVOS EM C#
TRATAMENTO DE
UTILIZANDO O THROW
EXCEÇÕES
UTILIZANDO USING
MÉTODOS DE EXTENSÃO
(EXTENSION METHODS)
PREDICATE
DELEGATE
ACTION
FUNÇÕES ANÔNIMAS:
EXPRESSÕES LAMBDAS E
MÉTODOS ANÔNIMOS
LINQ (LANGUAGE
INTEGRATED QUERY)
Foi criada uma classe Arquivo que terá métodos com a responsabilidade de Criar, Escrever e
Ler um arquivo texto.
O exemplo da Figura 1, contém uma classe com três métodos com a seguinte estrutura:
• Não foi necessário criar uma Instância da classe File, pois ela e seus métodos são estáticos.
• Nas Linhas 15 e 16, é solicitada a leitura do texto que será armazenado no arquivo.
• Na Linha 17, o método do objeto arq que é do tipo da classe Arquivo, é invocado,
passando como argumentos o nome e endereço do arquivo e o conteúdo a ser
armazenado. Note que foi adicionado o símbolo @, este procedimento serve para
duplicar as barras (\). No exemplo, a string final será: “D:\\temp\\meuarquivo.txt”. A
necessidade de utilizar duas barras está relacionada com estrutura da linguagem C# e
o Sistema Operacional.
Agora, vamos criar um exemplo, utilizando o FileStream para salvar e pesquisar o conteúdo do
arquivo.
• Entre as Linhas 14 e 16, foi criada uma estrutura utilizando a classe estática File para
verificar se o arquivo existe, caso exista, o arquivo será excluído.
• Na linha 18, foi criado um objeto do tipo StreamWriter com nome file que será utilizado
para criar e gravar o conteúdo no arquivo. Note que foi utilizado o método construtor do
StreamWriter, passando como argumento a variável arquivo. Você deve estar pensando:
o que significa o using? Não se preocupe, pois mais adiante no texto vamos descobrir!
• A estrutura do while percorre o arquivo linha por linha, onde a cada linha encontrada,
o conteúdo é armazenado na variável linha. Em seguida, na Linha 31, foi criada uma
concatenação para agrupar todo o conteúdo encontrado no arquivo.
• No final da busca, é realizado um retorno com o conteúdo que foi encontrado (Linha
35).
A Figura 4, representa a estrutura que solicita o conteúdo a ser armazenado e mostra o conteúdo
na tela. Note que a estrutura é idêntica ao exemplo apresentado na Figura 2, por este motivo,
não vamos detalhar a sua estrutura.
VAMOS PRATICAR?!
Exercício Resolvido 1:
Utilizando os exemplos apresentados anteriormente, crie um
programa orientado a objetos para receber o nome do arquivo
e endereço do arquivo. Após receber os dados, arquivo deve ser
salvo. Crie na classe de manipulação de arquivos, um método que
realiza a cópia do conteúdo de dois arquivos, este método deve
receber como parâmetros os nomes e endereços dos arquivos.
saiba mais!
Para conhecer a estrutura completa do FileStream, clique aqui.
2 - TRATAMENTO DE EXCEÇÕES
Durante a manipulação de um arquivo, podem ocorrer exceções, por exemplo, um bloqueio
de acesso do sistema operacional, um arquivo que não existe, ou seja, qualquer exceção
inesperada. Então, como tratar essas exceções?
Em muitos casos, uma exceção pode ser lançada, não por um método que seu código
chamou diretamente, mas por outro método, mais abaixo na pilha de chamadas. Quando
isso acontecer, o CLR desempilha a pilha, procurando por um método com um bloco catch
para o tipo de exceção específico. Então, primeiro, o bloco catch que for encontrado será
executado. Se não for encontrado nenhum bloco catch apropriado na pilha de chamadas, o
processo será encerrado e exibirá uma mensagem para o usuário (MICROSOFT, 2019).
• Se ocorrer um erro entre as Linhas 28 e 38, é lançada uma exceção e o código da linha
41 ou 45 serão executados.
• Note que existem dois blocos catch, isto é comum e pode ser utilizado, pois, o primeiro
catch trata um erro específico de leitura e entrada, ou seja, se ocorrer um erro durante a
leitura do arquivo, o primeiro bloco será executado. O segundo bloco é um tratamento
de erro genérico, ou seja, se o erro não for relacionado à arquivos, o segundo bloco será
executado.
• Note que dentro dos blocos catch, foi utilizado o objeto erro para mostrar a mensagem
de exceção na tela.
• Quando ocorre uma exceção no bloco try, o fluxo de controle vai para o primeiro
manipulador de exceção associado, que está presente em qualquer lugar na pilha de
chamadas. No C#, a palavra-chave catch é usada para definir um manipulador de
exceção.
• Não capture uma exceção, a menos que você possa manipulá-la e deixar o aplicativo
em um estado conhecido. Se você capturar System.Exception, relance-o usando a
palavra-chave throw no final do bloco catch.
• Se um bloco catch define uma variável de exceção, você pode usá-lo para obter
mais informações sobre o tipo de exceção que ocorreu.
• O código em um bloco finally será executado, mesmo se uma exceção for lançada.
• Utilize um bloco finally para liberar recursos, por exemplo, para fechar todos os fluxos
ou arquivos que foram abertos.
Fonte: MICROSOFT (2019).
Outra aplicação do throw seria a utilização para gerar novamente, uma exceção tratada em
um bloco catch. Neste caso, o throw não utiliza um operando de exceção.
No exemplo da Figura 8, se for passado um valor fora do índice será gerada uma exceção e o
throw dispara para o método chamador.
saiba mais!
Para conhecer a estrutura completa do tratamento de exceção, clique aqui.
3 - UTILIZANDO USING
Nessa aula, foi o utilizado o termo using. Então, vamos compreender qual a sua aplicação. O
using garante que Dispose que é responsável por liberar a memória, antes do coletor de lixo
(Garbage Collector) entre em ação. Você pode obter o mesmo resultado, colocando o objeto
dentro de um bloco try e então, chamando Dispose em um bloco finally. Na verdade, é dessa
forma que a instrução using é convertida pelo compilador. De acordo com a MICROSOFT, o
using possui três aplicações:
ii) a diretiva using cria um alias para um namespace ou importa tipos definidos em
outros namespaces;
A seguir, temos um exemplo da utilização do using. Note que a estrutura responsável por ler um
arquivo foi adicionada dentro do using.
O código presente na Figura 9, representa a criação de uma classe para inserir as extensões no
tipo DateTime, conforme detalhado a seguir:
• Toda classe, que possui método de extensão, deve ser estática (static).
• Na Linha 11, perceba que foi criado um método com nome DataPorExtenso. Nos
parâmetros foi adicionar o termo this, que indica que é um método de extensão que
será adicionado dentro do tipo Datetime. Para utilizar o método, não é necessário passar
uma data para o parâmetro objeto, além disso, como é uma extensão, ele pode ser
utilizado em qualquer variável do tipo DateTime.
• A Linha 13, retorna o mês atual, de acordo com a informação regional de idioma do
sistema operacional.
• Na Linha 14, a variável recebe a data por extenso, em seguida, o valor é retornado.
O exemplo da Figura 10, mostra como utilizar um método de extensão, com as seguintes
características:
• Entre as Linhas 13 e 15, foi criada uma variável do tipo DateTime e solicitado a data que
deseja utilizar.
Você pode utilizar métodos de extensão para estender uma classe ou interface, mas não para
substituí-los. Um método de extensão, com o mesmo nome e assinatura que um método de
interface ou classe, nunca será chamado. Em tempo de compilação, os métodos de extensão
sempre têm menor prioridade que os métodos de instância definidos no próprio tipo. Em outras
palavras, se um tipo possuir um método chamado Processar(int i), e se você tiver um método
de extensão com a mesma assinatura, o compilador sempre se associará ao método de
instância. Quando o compilador encontra uma invocação de método, primeiro ele procura
uma correspondência nos métodos de instância do tipo. Se nenhuma correspondência for
encontrada, ele irá procurar todos os métodos de extensão definidos para o tipo e associará
ao primeiro método de extensão que encontrar (MICROSOFT, 2019).
DICA DO AUTOR
A extensão pode ser uma estrutura importante para organizar o código e definir
algumas extensões de classe e interfaces. Porém, antes de utilizar, analise as
vantagens e desvantagens dentro do produto de software que será desenvolvido.
Lembre-se que cada produto de software pode possuir características diferentes.
Além disso, analise se herança não seria uma melhor opção.
VAMOS PRATICAR?!
Exercício Resolvido 3:
Crie uma classe de extensão para o tipo Decimal. Esta classe deve
conter um método de extensão responsável por receber um valor
decimal e retornar à descrição por extenso. Por exemplo, se for
passado 10,90, deve retornar: dez reais e noventa centavos.
Delegates são utilizados para passar métodos, como argumento a outros métodos. Por outro
lado, os manipuladores de eventos nada mais são, do que métodos chamados por meio de
delegates. Ao criar um método personalizado, uma classe como um controle do Windows
poderá chamá-lo quando um determinado evento ocorrer (MICROSOFT, 2019).
! FIQUE ATENTO!
Na linguagem C#, existem três tipos de delegates pré-definidos: Func, Action e Predicate. Mas
adiante, vamos analisar as suas aplicações. Entretanto, antes de analisar esses tipos, vamos
aprender como utilizar o delegate.
Na aula anterior, criamos um programa com uma classe para calcular o juro composto e
simples, então vamos utilizar os mesmos exemplos.
O exemplo da Figura 12, representa uma classe Calculo, que possui dois métodos para calcular
o juro composto e simples. Note que, a quantidade de parâmetros é idêntica, entretanto o
cálculo é diferente.
• Na Linha 9, é criado o delegate com nome CalculandoJuros que informa que a assinatura
deve receber dois parâmetros do tipo double e um do tipo int. Note que a criação deve
ser antes da declaração do nome da classe.
• Entre as Linhas 14 e 21, é criado a estrutura para receber o valor do capital, taxa de juro
mensal e quantidade de meses.
• Nas Linhas 23 e 24, são atribuídos dois valores delegate. O primeiro é o cálculo do juro
composto, o segundo de juros simples. Então, os itens composto e simples a partir deste
momento, representam as funções JuroComposto e JuroSimples.
• Nas Linhas 26 e 27, composto e simples são utilizados para calcular os valores. Em seguida,
o resultado é apresentado na tela.
O interessante que, o delegate CalculandoJuros pode receber qualquer método que tenha a
mesma assinatura, ou seja, dois parâmetros do tipo double e um inteiro.
saiba mais!
Seria possível substituir o exemplo de delegate apresentado nas Figuras 12 e 13 por
multcast delegates. Para saber mais, clique aqui.
A seguir, teremos dois exemplos dos delegates Predicate e Action. Mais adiante, teremos
exemplos do Func ao utilizarmos o LINQ.
5.1 - PREDICATE
O delegate predicate define uma função que recebe um objeto do tipo T e retorna um valor
booleano.
• Foi criado um método construtor entre as linhas 14 e 18, para receber o código e o nome do
aluno. Como já foi descrito em outro momento, o termo this conforme apresentado neste
exemplo, serve para identificar o item é uma propriedade ou variável da classe.
• Na linha 20, temos algo novo. Note que, o método ToString() foi sobreposto. Como já foi
discutido em outra aula, toda classe herda da classe Object, e o método ToString() é um
método virtual da classe Object que pode ser sobreposto. Então, conforme a estrutura deste
método, ao chamar o método ToString(), será retornado a concatenação entre o código
e o nome do aluno.
• Entre as Linhas 13 e 17, é criada a lista e são adicionados 4 objetos do tipo Aluno na Lista.
• Na linha 25, está o exemplo de predicate, utilizando o RemoveAll da lista. Note que foi
criado uma expressão lambda “p => p.codigo <=0”, para remover todos os alunos com
código menor ou igual a zero. Você deve estar pensando: o que é expressão lambda?
Fique tranquilo, mais adiante na disciplina vamos discutir sobre este assunto.
5.2 - ACTION
Action encapsula um método que tem um único parâmetro e não retorna um valor. Vamos
analisar um exemplo prático.
Utilizando a mesma estrutura do exemplo anterior, vamos somar o número 100 em todos os
códigos dos alunos. Por exemplo, 1 será igual a 101 e assim por diante. Neste momento, seria
possível utilizar uma função lambda, mas para criarmos um exemplo diferente, vamos criar um
método para realizar a soma.
O exemplo da Figura 16, realiza a manipulação da lista e utiliza o action com as seguintes
características:
• Entre as Linhas 29 e 32, foi criado um método que recebe um objeto do tipo Aluno e realiza
a soma do código mais 100.
• A Linha 19, representa o action. Note que foi utilizado o ForEach e passado como argumento,
o nome do método Atualizar. Então, todos os itens da lista serão atualizados. Em seguida, os
dados são apresentados na tela (Linhas 22 a 25).
No lugar do método, seria possível utilizar uma função lambda, conforme o exemplo a seguir.
Neste exemplo, não é utilizado o método. E ao colocar o código lambda entre chaves, indica
que não terá retorno
Uma função anônima é uma instrução “in-line” ou expressão que pode ser usada sempre que
um tipo de delegate é esperado. Podemos usá-las para inicializar um delegate nomeado ou
passar uma função anônima, em vez de um tipo de delegate nomeado como um parâmetro
de método (MICROSOFT, 2019). Existe dois tipos de funções anônimas: Expressões lambda e
métodos anônimos.
Nas versões anteriores à versão 2.0 da linguagem C#, a única maneira de declarar um delegate
era usando métodos nomeados. A partir da versão 2.0, a linguagem C# introduziu os métodos
anônimos e no C# 3.0 e posterior, as expressões lambdas substituem os métodos anônimos
como a melhor maneira de escrever código “in-line”. Uma expressão lambda é uma função
anônima que pode conter expressões e instruções e pode ser usada para criar delegates ou
tipos de árvore de expressão (MICROSOFT, 2019).
Todas as expressões lambdas utilizam o operador => o que significa “vai para”. A sintaxe geral
de uma expressão lambda pode ser expressa como:
No lado esquerdo do operador lambda, temos os parâmetros de entrada, que podem ser tipos
implícitos ou explícitos, a serem passados para o método. No lado direito temos o método,
expressão ou bloco de código que será executado.
No exemplo acima, são impressos os números ímpares na tela. Entretanto, o responsável por
apresentar os valores na tela é o foreach. Neste exemplo, foi utilizado o conceito de LINQ,
que será detalhado adiante no texto. Neste exemplo, é aplicado o delegate Func, que já
comentamos nessa aula.
No exemplo acima (Figura 18), foi utilizado outro exemplo de uma expressão lambda. Note que
saiba mais!
Alguns exemplos desta Seção foram retirados desse material aqui.
Não vamos estudar os detalhes sobre função anônima, pois, atualmente a expressão
lambda pode ser utilizada para substituí-la. Mas se quiser conhecer detalhes sobre
funções anônimas, clique aqui.
O exemplo a seguir, mostra como as três partes de uma operação de consulta são expressas
em código-fonte. O exemplo usa uma matriz de inteiros como uma fonte de dados. Considere
que os mesmos conceitos, também se aplicam a outras fontes de dados com uma lista de
dados.
No exemplo da Figura 19, na linha 15 é criado um vetor com 7 valores. Entre as linhas 19 e 22,
está a consulta (query). Entre as linhas 25 e 28, é executada a pesquisa pelo LINQ. Note que,
somente a criação da consulta (Linhas 19 a 22) não executa a consulta, ou seja, é necessário
a execução do foreach.
Conforme afirmado anteriormente, uma consulta LINQ precisa de três estruturas: 1) o data
source onde estão os dados, ou seja, uma base de dados, vetor, etc; 2) a estrutura da consulta
(query); 3) a execução da consulta.
Com base no exemplo da Figura 19, vamos criar mais exemplos para auxiliar na compreensão.
No exemplo a seguir, vamos criar uma classe ControleNumero, que contém um método que
recebe um parâmetro do tipo inteiro e apresenta na tela, todos os números do vetor maior
que o valor passado como argumento. Um detalhe, para utilizar o LINQ é necessário declarar
o namespace System.Linq.
• Na Linha 14, é criado um vetor com 10 posição, com valores de 0 a 10. Esta estrutura
representa a fonte de dados (data source)
• Entre as Linhas 16 e 18, é realizada a consulta LINQ utilizando uma expressão idêntica ao
SQL. Esta estrutura representa a consulta (query).
• A variável numQuery é do tipo IEnumerable<>. Então, você pode substituir o var por
IEnumerable<int>.
Fantástico! Você agora sabe utilizar o LINQ na linguagem C#. Na próxima aula, vamos estudar
mais alguns exemplos com LINQ! Agora tente resolver o exercício proposto a seguir, para
concretizar o seu aprendizado.
VAMOS PRATICAR?!
Exercício Resolvido 4:
Altere o exemplo apresentado anteriormente e crie um segundo
método na classe ControleNumero, que pesquise apenas
os números pares de um vetor. Apresente na tela, os valores
multiplicados por 10. Para facilitar, coloque o vetor como atributo
de classe, para que seja utilizado pelos dois métodos.
aUTOaVALIAÇÃO
Após essa aula, você é capaz de desenvolver pesquisas utilizando LINQ?
É capaz de aplicar tratamento de exceção? Consegue criar métodos de
extensão? Caso você consiga responder estas questões, parabéns! Você
atingiu os objetivos específicos da Aula 6! Caso tenha dificuldades para
responder alguma(s) dela(s), aproveite para reler o conteúdo da Aula,
acessar o UNIARAXÁ Virtual e interagir com seus colegas e com o(a) tutor(a)
e esclarecer todas as suas dúvidas. Você não está sozinho nessa caminhada!
Conte conosco!
RECAPITULANDO
Caro(a) Aluno(a), chegamos ao fim da nossa aula. Espero que tenha compreendido o conteúdo
e resolvido os exercícios. Estudamos sobre manipulação de arquivos, métodos de extensão,
delegates, LINQ, expressões lambda e outras estruturas da linguagem C#.
Muito bem! Em nossa próxima Aula, vamos continuar nosso estudo sobre Programação
Orientada a Objetos, porém, vamos trabalhar com desenvolvimento de aplicações gráficas
utilizando o Windows Forms.
VIDEOAULA
Após a leitura e o estudo do seu livro-texto, chegou o momento de
complementar seu conhecimento. Vá até seu Ambiente Virtual
de Aprendizagem e acesse a Videoaula referente à Aula.
AULA 7
Objetivos Específicos:
Nessa aula, vamos estudar outros exemplos sobre LINQ, desenvolvimento de projetos utilizado
uma interface gráfica e criação de DLLs. Então, é indispensável que você tente resolver todos
os exercícios propostos.
No final dessa Aula, você será capaz de trabalhar com projetos Windows Forms, desenvolver
pesquisas utilizando o LINQ e outros conceitos da linguagem C#. Você sabe trabalhar com
DLL? Consegue desenvolver projetos Windows Forms? Nessa aula, você terá as respostas para
essas outras perguntas.
! FIQUE ATENTO!
Boa aula!
DESENVOLVENDO SOFTWARE
ORIENTADO A OBJETOS - PARTE V
OUTROS EXEMPLOS
DE LINQ (INTEGRATED
LANGUAGE QUERY)
CRIANDO O PRIMEIRO
EXEMPLO WINDOWS
FORMS
CRIANDO UM EXEMPLO
DE APRESENTAÇÃO DE
DADOS
CRIANDO O PRIMEIRO
PROJETOS CLASS LIBRARY EXEMPLO DE CLASS
(BIBLIOTECA DE CLASSES) LIBRARY (BIBLIOTECA DE
CLASSES)
Então vamos lá! Para finalizar o aprendizado sobre LINQ e Expressões lambda, vamos desenvolver
o nosso último exemplo!
Agora vamos criar um exemplo na classe Program para manipular as duas classes, por meio de
instâncias e lista. Vamos criar quatro instâncias da classe Departamento e uma lista com várias
instâncias da classe Funcionario. Em seguida, vamos desenvolver algumas pesquisas utilizando
o LINQ com expressões Lambda.
Note que no exemplo da Figura 3, foram criadas quatro instâncias para o Departamento entre
as linhas 14 e 17. Em seguida, a partir da linha 19, foi criada uma lista do tipo Funcionario
e adicionados quatro funcionários. Este tipo de estrutura pode ser utilizada para facilitar a
inserção de instâncias em uma lista. Note que, para cada instância do funcionário na lista, foi
adicionado uma instância do seu departamento de trabalho. A seguir, vamos apresentar a
segunda parte, com algumas pesquisas utilizando o LINQ.
• Entre as linhas 23 e 31, são apresentados na tela, todos os clientes com código acima
de 1012. Note que na linha 27, é utilizado um exemplo do LINQ com a utilização de uma
expressão lambda para retornar todos os clientes com código maior que 1012 (P =>
P.codigo > 1012). Esta expressão lambda é um dos exemplos que podem ser utilizados
para realizar pesquisas. Além disso, foi necessário realizar o foreach para apresentar os
dados na tela.
• Entre as linhas 33 e 38, é apresentado na tela todos os funcionários que possuem o nome
começando com a letra A (P => P.nome[0] ==’A’). No mesmo exemplo, foi aplicado uma
restrição para selecionar apenas o nome (Select(p=> p.nome)). Em seguida, foi realizado
um foreach para apresentar o resultado na tela. Note que, para imprimir foi necessário
utilizar apenas o item (Console.WriteLine(item)), ou seja, não foi necessário adicionar
“.nome”. Note que, ao passar o valor ‘A’, foi utilizado aspas simples (apóstrofo), pois
dados é um char e não uma string.
• Entre as linhas 40 e 45, são apresentados na tela, todos os funcionários que nasceram no
ano 2000. Além disso, foi adicionada uma opção para que os dados sejam apresentados
na ordem crescente de nome (OrderBy(p => p.nome)).
Fantástico! Mas vamos alterar o nosso código e acrescentar outros exemplos. Inicialmente,
vamos alterar o código da classe Funcionario, sobrescrevendo o método toString(), conforme
o exemplo a seguir.
Note no exemplo da Figura 5, o método ToString() foi sobrescrito. Esta alteração retornará à
concatenação do código, nome e data de nascimento do funcionário.
Agora vamos alterar a classe Program, para utilizar esta alteração. Mas antes, vamos adicionar
um método que será responsável por imprimir os resultados das pesquisas.
DICA DO AUTOR
Se você não lembra como manipular um tipo de dado DateTime, leia novamente
a Aula 02.
Parabéns!!!! Você já está preparado para utilizar o LINQ. Entretanto, note que utilizamos alguns
exemplos que representam apenas uma parte das possibilidades do LINQ. Contudo, espero
que esteja familiarizado com a estrutura LINQ, pois este conteúdo é amplamente utilizado em
projetos C#.
VAMOS PRATICAR?!
Exercício Resolvido 1:
Crie um projeto com as classes Produto e Departamento, onde
Departamento deve conter o código e a descrição. Produto deve
conter código, descrição, preço de venda e uma instância do
departamento. Utilizando o exemplo apresentado anteriormente,
realize a pesquisa dos produtos que possuem o preço maior que
100,00 e apresente na tela. Fique à vontade para criar outros
exemplos de LINQ.
saiba mais!
A estrutura de LINQ pode ser utilizada em qualquer ambiente. Seja em um projeto Web
MVC, Core, entre outros. Acesse esse link aqui, para conhecer mais detalhes.
Até o momento, utilizamos apenas projetos Console Application, pois o objetivo foi facilitar o
aprendizado sobre a linguagem C# e os conceitos de Programação Orientada a Objetos. A
partir do próximo tópico, vamos iniciar o nosso aprendizado sobre a criação de projetos com
Interface gráfica utilizando Windows Forms.
Em C# existem vários tipos de projetos com interface gráfica, um deles, é baseado em Windows
Forms, ou seja, desenvolvimento baseado em formulários. Formulários são a unidade base do
Com o Windows Forms, você desenvolve clientes inteligentes. Clientes inteligentes são aplicativos
graficamente ricos que são fáceis de implantar e atualizar, podem funcionar quando eles estão
conectados ou desconectados da Internet e podem acessar recursos no computador local de
maneira mais segura do que os aplicativos tradicionais baseados no Windows. Windows Forms
é uma tecnologia de cliente inteligente para o .NET Framework, é um conjunto de bibliotecas
gerenciadas que simplificam tarefas comuns de aplicativos, como leitura e gravação para
o sistema de arquivos. Quando você usa um ambiente de desenvolvimento como o Visual
Studio, você pode criar aplicativos Windows Forms que exibem informações, solicitam entrada
de usuários e se comunicam com computadores remotos em uma rede. Nos Windows Forms,
um formulário é uma superfície visual, na qual são exibidas informações para o usuário.
Normalmente, os aplicativos são compilados com o acréscimo de controles a formulários e de
respostas de desenvolvimento a ações do usuário, como cliques do mouse ou pressionamento
de teclas. Vale ressaltar que um controle é um elemento discreto de interface do usuário, que
exibe dados ou aceita a entrada de dados.
Um projeto Windows Forms possui uma estrutura idêntica aos projetos Console que utilizamos
nos exemplos anteriores. A diferença é que, a partir de agora, você terá que lidar com uma
interface gráfica responsável por apresentar e manipular conteúdos. A seguir, vamos analisar
os dois arquivos responsáveis por manipular, controlar eventos e construir a estrutura de um
formulário.
Resumindo, cada formulário possui dois arquivos, o .cs que possui os eventos e possíveis métodos,
e o .Design.cs que terá as propriedades e configurações dos componentes e do formulário.
! FIQUE ATENTO!
saiba mais!
A Microsoft fornece uma guia de boas práticas para nomear os objetos de projetos.
Por exemplo, qual seria o nome ideal para um button? Acesse o link aqui e veja mais
detalhes.
Conforme a Figura 12, para adicionar um botão e um campo para digitar um texto, é necessário
acessar o menu View e selecionar ToolBox. Em seguida, a barra de ferramenta é apresentada do
lado esquerdo, então, você pode selecionar os itens desejados e arrastá-los para o formulário.
No exemplo, arrastamos um button e um textbox. E ao clicar com botão direito no objeto,
é possível alterar suas propriedades. No nosso exemplo, alteramos o name do textbox para
txtMensagem, o name do button para btnMostrar. Além disso, alteramos o texto apresentado
pelo button para Mostrar Mensagem.
O trecho de código a seguir mostra o que foi alterado no arquivo Form1.Design.cs ao adicionar
e alterar o button e o textbox no Form1. Note que foi criada uma instância do tipo do button
e textbox, em seguida foi adicionada as configurações de localização, nome e outras
propriedades dos componentes. Entendeu porque eu disse que geralmente não é necessário
alterar este arquivo? Pois nesse exemplo, ao trabalhar na parte gráfica, o Visual Studio atualizou
o arquivo automaticamente. Fantástico, isto parece mágica!
Figura 13: Alteração no arquivo Form1.Design.cs ao adicionar e alterar o button e o textbox no Form1
Agora vamos mostrar uma mensagem na tela com conteúdo que for digitado no campo de
texto. Basicamente, existem duas formas de realizar este procedimento. Você pode selecionar
o botão e clicar no ícone de evento na barra de propriedade do botão. Ao clicar, note que
existem vários eventos, entre eles o Click, e ao clicar duas vezes sobre o nome do evento é
criado o evento do Click no arquivo Form1.cs, conforme a Figura 14. O segundo caminho é
Agora, vamos criar uma classe Poupanca que herda da classe Conta. Note na Figura 17, que a
classe herda da classe Conta. Além disso, o método Sacar é sobrescrito.
A seguir, vamos criar um formulário com nome frmDepSacar, com os dados para simular um
depósito.
A Figura 18, representa o formulário que vamos utilizar para simular um depósito ou saque. Note
que foi utilizado dois textbox, um com nome txtvalor para receber valor do depósito, outro com
nome txtsaldo para receber o saldo após a execução. E para controlar o tipo da execução
(depositar ou sacar), foi criado um combobox com nome cbotipo para receber o tipo da
execução. Por fim, foi criado um botão (button) com nome btnexecutar para executar a ação.
O componente combobox pode ser utilizado para receber uma coleção de dados de um
repositório ou ser preenchido manualmente. Neste exemplo realizamos o seu preenchimento
manualmente com os valores Depositar e Sacar (Figura 19). Note que os valores estão em linhas
distintas, então, automaticamente, eles recebem como índice (index) os valores 0 e 1.
Agora, vamos simular o depósito. Mas antes, conforme o exemplo a seguir, vamos alterar
a classe Program e informar que o primeiro formulário a ser executado será o frmDepSacar,
conforme o exemplo a seguir.
O exemplo da Figura 20, representa a estrutura para realizar o depósito ou saque na classe
Poupanca. Como não estamos utilizando um repositório de dados, criamos uma estrutura para
simular um saldo inicial. A seguir temos mais detalhes:
• Na linha 15, foi criado uma instância (objeto) da classe Poupanca. Perceba que a
instância foi criada como objeto do formulário e não dentro de um evento ou método.
Então, assim que o formulário for criado, o objeto será instanciado.
• Entre as linhas 26 e 38, está a estrutura do evento do clique no botão executar. Foi
criado um teste para analisar que tipo de atividade que será realizada, depósito
(selectedindex==0) ou sacar (selectedindex==1). Por fim, na linha 37, o saldo atual é
apresentado na tela.
VAMOS PRATICAR?!
Utilizando como base o exemplo sobre contas. Crie uma classe
Corrente que herda da classe Conta e simule o depósito e saque
nesta conta.
A classe na Figura 21, representa a relação de composição entre Lista e Telefone. Note que a
composição define que uma lista é composta por uma coleção de telefones. Então, dentro da
classe Lista teremos uma lista de objetos do tipo Telefone.
A Figura 22, representa a classe Telefone. Note que existem apenas três propriedades. Vale
lembrar que, no diagrama da Figura 21, as propriedades estão representadas por atributos de
classe, pois não existe representação de propriedades na estrutura UML.
• Na linha 12, o método Adicionar recebe como parâmetro um objeto do tipo Telefone,
que possui a responsabilidade de adicionar o objeto na lista.
• Na linha 17, o método Remover recebe como parâmetro um objeto do tipo Telefone, e
possui a responsabilidade de remover o objeto da lista.
• Entre as linhas 20 e 30, está a estrutura do evento do clique no botão salvar. Na linha
22, é criado um objeto do tipo da classe Telefone. Entre as linhas 23 e 26, os dados do
telefone são adicionados na lista. Note que na linha 26, foi utilizado o objeto lista e o
método Adicionar, passando o objeto telefone como parâmetro. Entre as linhas 27 e 29,
é realizada a pesquisa dos telefones cadastrados e o resultado é apresentado na tela
por meio do componente DataGridView. Por fim, o Refresh é utilizado para atualizar os
dados que foram inseridos, mas geralmente em software Windows Forms não é necessário
utilizá-lo. A Figura 26, representa um exemplo do cadastro de dois telefones na lista.
• Entre as linhas 31 e 34, é realizada uma pesquisa de telefone de acordo com número
digitado no txtnumeropesquisa. Note que ao realizar este procedimento o resultado da
pesquisa é apresentado no DataGridView.
VAMOS PRATICAR?!
Crie duas classes Banco e Conta. Onde Banco terá uma
composição de objetos do Tipo Conta. A manipulação deve ser
idêntica ao exemplo que acabamos de estudar. Ou seja, com
opções para salvar e pesquisar contas dentro do formulário.
! FIQUE ATENTO!
Uma DLL (Dynamic Link Library) é uma extensão de arquivo muito presente no Windows, é uma
biblioteca dinâmica com dados que podem ser acessados por vários programas instalados
no computador. Uma DLL contém código e dados que podem ser usados por mais de um
programa ao mesmo tempo. Por exemplo, em sistemas operacionais Windows, a DLL Comdlg32
executa funções comuns relacionadas à caixa de diálogo. Portanto, cada programa pode
usar a funcionalidade contida dessa DLL para implementar uma caixa de diálogo. Isso ajuda
a promover a reutilização de código e o uso de memória eficiente. Ao usar uma DLL, um
programa pode ser modularizado em componentes separados. Por exemplo, um programa de
contabilidade pode ser vendido por módulo de DLL. Cada módulo pode ser carregado para
o programa principal em tempo de execução se o módulo é instalado. Como os módulos são
separados, o tempo de carregamento do programa é mais rápido e um módulo é carregado
somente quando essa funcionalidade é solicitada. Além disso, as atualizações são mais fáceis
de serem aplicadas a cada módulo, sem afetar outras partes do programa. Por exemplo, você
pode ter um programa de folha de pagamento com as taxas de impostos calculadas por meio
de uma DLL e, quando surgir alguma alteração nos cálculos, essa DLL pode ser atualizada sem
a necessidade de criar ou instalar o programa novamente (MICROSOFT,2019).
A lista a seguir descreve algumas das vantagens que são fornecidas quando um programa usa
uma DLL (MICROSOFT,2019):
• Utiliza menos recursos quando vários programas usam a mesma biblioteca de funções,
uma DLL pode reduzir a duplicação de código que é carregado no disco e na memória
física. Isso pode influenciar o desempenho não apenas do programa que está sendo
executado em primeiro plano, mas também outros programas em execução no sistema
operacional Windows.
Então vamos lá! Para criar um projeto, basta acessar o Visual Studio e criar um projeto Class
Library, conforme a Figura 27.
Perceba que ao criar o projeto, é fornecida uma estrutura com uma classe (class1) e outros
arquivos. Neste momento, você deve estar pensando: posso utilizar os conceitos de Programação
Orientada a Objetos? Claro que sim, pois a diferença básica deste tipo de projeto é que, ele
não gera um instalador ou execução, e sim uma DLL com resultado da estrutura que foi criada.
Agora vamos criar neste projeto uma classe com nome CalculoJuro.
Agora, vamos testar a nossa DLL. Como foi apresentado nas primeiras aulas, ao criar um projeto
no Visual Studio é criado uma Solution. Uma Solution é uma estrutura que pode conter vários
projetos. Então dentro da mesma Solution do Projeto Class Library que acabamos de criar,
vamos adicionar um projeto Windows Forms para testar a DLL. Para criar o projeto clique com
botão direito no nome da Solution em seguida Add e new Project.
Atenção: você poderia realizar basicamente o mesmo exemplo que vamos apresentar em
uma classe.
A Figura 32 representa o código de cálculo de juros consumindo a DLL que foi criada, com as
seguintes características:
• Na linha 4, foi adicionado o namespace da DLL. Isto é uma das formas de utilizar a
• O restante do código, entre as linhas 18 e 21, recebe os valores que foram digitados
nos campos de texto (textbox), invoca o método para calcular os juros e apresenta o
resultado na tela.
Fantástico! Agora você sabe o que significa uma DLL e como utilizá-las. Ops! É claro, você
sabe como criá-la!
VAMOS PRATICAR?!
Utilizando mesmo projeto, crie um método para calcular o juro
simples e crie um formulário para testar este cálculo.
saiba mais!
Existem várias bibliotecas prontas que podem ser utilizadas. Por exemplo, existem
bibliotecas criadas para manipulação de imagens, conexão com repositórios de dados
e outras ações. Além disso, as DLLs podem ser free, open source ou proprietárias. Para
conhecer algumas dessas DLLs, clique aqui.
RECAPITULANDO
Caro(a) Aluno(a), chegamos ao fim da nossa aula. Espero que tenha compreendido o
conteúdo e resolvido os exercícios. Estudamos sobre LINQ e expressões lambda, criação de
projetos Windows Forms e criação de DLLs.
Muito bem! Em nossa próxima Aula, vamos realizar uma revisão geral sobre os conceitos de
programação orientada a objetos por meio de exemplos práticos. Além disso, vamos discutir
sobre serialização e outros exemplos da linguagem C#.
VIDEOAULA
Após a leitura e o estudo do seu livro-texto, chegou o momento de
complementar seu conhecimento. Vá até seu Ambiente Virtual
de Aprendizagem e acesse a Videoaula referente à Aula.
SHARP, John; MANIEZ, Dominique. Visual C# 2010. Microsoft Press, 2010. Porto Alegre: Bookman,
2011.
AULA 8
Objetivos Específicos:
Ao final desta aula, você será capaz de trabalhar com tipos genéricos, serialização e
deserialização de objetos, reflection e outras estruturas da linguagem C#. Você sabe trabalhar
com tipos genéricos? Consegue serializar e deserializar objetos? Nessa aula, você terá as
respostas para essas e outras perguntas.
Boa aula!
OUTRAS ESTRUTURAS DA
LINGUAGEM C# E REVISÃO SOBRE
POO
CLASSES GENÉRICAS
TIPOS GENÉRICOS
(CLASSES, INTERFACES E INTERFACES GENÉRICAS
MÉTODOS)
CRIANDO O NOSSO
EXEMPLO
O QUE É UM XML
(EXTENSIBLE MARKUP
LANGUAGE)
O QUE É UM JSON
SERIALIZAÇÃO DE (JAVASCRIPT OBJECT
OBJETOS NOTATION)
CRIANDO UM EXEMPLO
DE SERIALIZAÇÃO E
DESERIALIZAÇÃO DE
OBJETO
ENTENDENDO,
RELEMBRANDO ABSTRAINDO E
PROGRAMAÇÃO CONSTRUINDO O
ORIENTADA A OBJETOS MODELO
DICA DO AUTOR
Se não lembra como funciona o CLR da estrutura .NET, acesse o conteúdo da
nossa Aula 02.
saiba mais!
Para obter mais informações sobre o uso dessas classes, consulte Coleções genéricas no
site da Microsoft. Para acessar, basta clicar aqui.
Note que, no exemplo apresentado, a classe ClasseFechada é um tipo genérico que herda de
uma classe Genérica, entretanto, ao definir inserir o termo int, é definido que é uma BaseGenerica
de inteiros. Vale ressaltar que classes não genéricas ou, em outras palavras, classes concretas,
podem herdar de classes base construídas fechadas, mas não de classes construídas abertas
ou de parâmetros de tipo, porque não é possível fornecer o argumento de tipo necessário para
instanciar a classe base em tempo de execução. Por exemplo, não seria possível criar uma
classe que herde da classe ClasseAberta do exemplo anterior (MICROSOFT, 2019).
saiba mais!
Nessa aula, não vamos abordar os detalhes sobre Interface genérica. Mas se deseja
conhecer mais detalhes, clique aqui.
O exemplo da Figura 1 representa uma estrutura com 3 classes: Funcionario (classe pai),
Medico e Engenheiro (classe filhas). Além de uma terceira classe (PesquisarFuncionario), que
terá a responsabilidade de conter os métodos de pesquisa de funcionário. Perceba que a
classe Funcionario possui uma referência para ela mesma na propriedade chefe, isto indica
que um funcionário pode ter um chefe. Neste momento, temos o primeiro problema. Imagine
que na regra o médico possa ser chefiado, apenas por outro médico. Porém, nessa estrutura,
o médico pode ter qualquer chefe que herde de funcionário, ou seja, o médico pode ter um
chefe engenheiro.
A seguir, vamos criar um exemplo, utilizando métodos e classes genéricas para melhorar
a estrutura do exemplo apresentado. Entretanto, vale ressaltar que podem existir outras
alternativas para melhorar o código. Mas o nosso objetivo neste momento, é comparar as duas
estruturas, com e sem tipos genéricos.
• Na linha 19, Funcionario<T> define que funcionário é um tipo genérico. Além disso, a parte
do código where T : Funcionario<T> define que todas as classes que herdam da classe
genérica, obrigatoriamente, devem ser do tipo Funcionario.
• Note que a classe Medico, herda de Funcionario<Medico>, isto indica que, todo médico
não pode ser de outro tipo a não ser médico. Isto está relacionado com construtor fechado,
que já discutimos nesta aula. Além disso, a classe Engenheiro segue a mesma estrutura.
• Na linha 11, temos a assinatura do método genérico. Com esta estrutura, o método pode
receber qualquer objeto do tipo genérico Funcionario. A estrutura do Where define que
o tipo de retorno será um objeto genérico do tipo Funcionario. E como parâmetro, ela
recebe um T, que pode ser Medico ou Engenheiro, ou seja, qualquer objeto que herde
Funcionario<T>.
Espero que tenha compreendido as vantagens dos objetos genéricos. Neste exemplo, foi
apresentada uma estrutura básica para que você possa compreender sua aplicação. Para
finalizar, vamos analisar a visão geral de tipos genéricos (MICROSOFT, 2019).
saiba mais!
Existem outras estruturas de objetos genéricos. Então, para conhecer outros detalhes,
acesse aqui.
2. SERIALIZAÇÃO DE OBJETOS
Imagine que você tenha uma estrutura em uma classe, ou uma coleção de objetos em uma lista
e precisa armazenar os dados em arquivo binário, JSON ou XML. Por exemplo, para trabalhar
com algum documento obrigatório, como uma NFe (Nota Fiscal Eletrônica) ou atender algum
requisito de integração. Por outro lado, imagine que seja necessário acessar as informações
de um arquivo XML e preencher uma lista de objetos com resultado da pesquisa. Então, qual
seria a solução? Existem algumas opções para atender esses requisitos, entre elas, o processo
de serialização e deserialização de objetos.
GLOSSÁRIO
FIREWALL
É um dispositivo ou um
programa que tem por
objetivo aplicar uma política
de segurança em uma rede
Fonte: MICROSOFT (2019). de computadores.
W3C
O objeto é serializado em um fluxo que transporta não apenas
O World Wide Web
os dados, mas informações sobre o tipo de objeto, como sua
Consortium é a principal
versão, cultura e nome do assembly. Esse resultado pode
organização de
ser armazenado em um banco de dados, um arquivo ou
padronização da World
uma memória. A serialização permite que o desenvolvedor
Wide Web. Consiste em
salve o estado de um objeto e recrie conforme necessário,
um consórcio internacional
fornecendo o armazenamento dos objetos, bem como a
com quase 400 membros,
troca de dados. Pela serialização, um desenvolvedor pode
agrega empresas,
executar ações como enviar o objeto para um aplicativo
órgãos governamentais
remoto por meio de um serviço Web, passando um objeto
e organizações
de um domínio para outro, passando um objeto por um
independentes com a
firewall como uma cadeia de caracteres XML ou JSON, ou
finalidade de estabelecer
mantendo a segurança ou as informações específicas de
padrões para a criação e a
usuários entre aplicativos (MICROSOFT, 2019).
interpretação de conteúdos
Antes de criar os nossos exemplos, vamos descobrir o que para a Web.
significa XML e JSON, estruturas que podem ser criadas na
serialização.
Exemplo de XML
<cadastro>
<cliente>
<nome>José Objetos</nome>
<email>jose@objetos.com.br</email>
</cliente>
<cliente>
<nome>Maria Objetos</nome>
<email>maria@objetos.com.br</nome>
</cliente>
</cadastro>
Fonte: Elaborada pelo autor.
saiba mais!
Nosso objetivo não é explicar todos os detalhes sobre XML. Se quiser conhecer mais
detalhes sobre XML acesse o site da W3C. Basta clicar aqui. Ou assista a esse vídeo aqui.
Note que JSON possui uma estrutura mais próxima de uma linguagem de programação
procedimental, além de ser mais fácil de compreender.
saiba mais!
Nosso objetivo não é explicar todos os detalhes do JSON. Então, se quiser conhecer os
detalhes sobre este tipo de arquivo, clique aqui.
A Figura 8, representa a classe (Cliente) de objetos que será serializada. Note que foi adicionado
o termo [Serializable], que informa que a classe pode ser serializável. Entretanto, em alguns
casos isto não é necessário. Por outro lado, se quiser bloquear a classe para que não seja
serializável, basta adicionar [NonSerialized].
• Entre as linhas 21 e 26, está a estrutura do método CriarLista, responsável por adicionar
cinco clientes na lista.
• A linha 30, contém o contexto do método construtor do formulário. Dentro deste contexto,
a lista é criada ao invocar o método CriarLista.
Agora vamos analisar como é desenvolvida a serialização e deserialização dos objetos da lista
para um arquivo binário.
A Figura 10 representa o exemplo de serialização dos objetos da lista de Cliente para um arquivo
binário, com os seguintes detalhes:
• Note que, na linha 35, é utilizado o FileStream para criar um arquivo binário em uma
determinada pasta.
• Na linha 36, é criado um objeto do tipo que será responsável em serializar os objetos.
Note que na Figura 10, temos a estrutura de deserialização presente no evento do clique do
botão, btnDeserializarBin:
• Na linha 43, está a estrutura responsável em deserializar o objeto e armazenar em uma lista
com nome pesquisa. Em seguida, os valores são preenchidos no DataGridView (chamado
de griddados), conforme Figura 12. Os dados foram preenchidos, ao clicar no botão
Deserializar Binário.
A Figura 13, representa a estrutura de serialização e deserialização utilizando arquivo XML. Note
que a estrutura é idêntica ao manipular arquivo binário, a diferença básica está no tipo de
objeto que foi utilizado para serializar e deserializar, que pertence ao namespace System.Xml.
Serialization. Veja na Figura 14, o resultado da estrutura do arquivo ao serializar. Além disso, o
resultado ao clicar no botão Deserializar XML, será o mesmo apresentado na Figura 12.
saiba mais!
Acesse o link para descobrir o que significa e como utilizar o NuGet do Visual Studio.
Basta clicar aqui.
3. UTILIZANDO O LAZY
Quando em uma classe A é criada uma instância de uma classe B, todos os objetos da classe
B que estão como atributos, propriedades e métodos são criados na memória. Entretanto,
imagine que ao instanciar a classe A, você não deseja utilizar os objetos complexos, por
exemplo, uma lista de elementos de uma classe C ou uma instância da classe D. Será que seria
possível resolver este problema? Sim, com a utilização da estrutura Lazy.
Lazy de um objeto significa que a criação dele é adiada até que ele seja usado pela primeira
vez (Para este tópico, os termos inicialização lenta e instanciação lenta são sinônimos.)
A inicialização lenta (Lazy) é usada principalmente para melhorar o desempenho, evitar a
computação dispendiosa e reduzir os requisitos de memória do programa. Estes são os cenários
mais comuns (MICROSOFT, 2019). Um bom exemplo é quando você tem um objeto de criação
dispendiosa e o programa pode não vir a usá-lo durante sua execução. Por exemplo: você tem,
na memória primária, um objeto Cliente que possui uma propriedade Pedidos contendo uma
grande variedade de objetos Pedidos que, ao serem inicializados, requerem uma conexão de
banco de dados. Se o usuário nunca solicita a exibição dos Pedidos nem usa os dados em uma
computação, não há motivo para usar a memória do sistema ou ciclos de computação para
criá-lo. Ao usar Lazy<Pedidos> para declarar o objeto Pedidos para inicialização lenta, você
pode evitar desperdício de recursos de sistema quando o objeto não é usado (MICROSOFT,
2019).
! FIQUE ATENTO!
Quando você tem um objeto cuja criação é dispendiosa e você deseja adiar a criação até
após a conclusão de outras operações dispendiosas. Por exemplo, suponha que seu programa
carrega várias instâncias de objeto quando ele é iniciado, mas apenas algumas delas são
necessárias imediatamente. Você pode melhorar o desempenho de inicialização do programa,
adiando a inicialização dos objetos que não são necessários, até que os objetos necessários
tenham sido criados.
Note que a Figura 17, contém a estrutura de uma classe Conta. Foram criadas algumas
propriedades e um método construtor. Entretanto, note que na criação do tipo Cliente, foi
utilizado o Lazy. E ao instanciar o objeto na linha 16 do método construtor, foi inferido que o
objeto clienteconta é um tipo Cliente, porém utilizando Lazy.
Agora, vamos analisar como seria utilização da classe Conta. A seguir, temos o exemplo
utilizando a classe Program em um projeto Console Application.
• Entre as linhas 14 e 16, foi criada uma instância da classe Conta e adicionados os valores
para as propriedades.
• Na linha 18, é apresentado na tela se o objeto clienteconta que pertence ao tipo Cliente
foi instanciado. Note que o valor apresentado na tela é igual a False, ou seja, o objeto não
foi instanciado. Pois, lembra que definimos o Cliente como Lazy? Então, para acessar os
objetos complexos instanciados com a estrutura Lazy é necessário utilizar o termo Value.
• Na linha 19, foi apresentada a propriedade do nome do Cliente. Note que foi necessário
utilizar o Value antes do nome da propriedade. Então, a partir dessa execução o objeto
clienteconta foi instanciado. Note que na linha seguinte (20), ao analisar se existe uma
instância, é retornado o valor True.
Resumindo, o objetivo complexo somente foi instanciado a partir da linha 19, quando foi
necessário, mostrar o nome do cliente na tela. Isto parece mágica, não é verdade!?!?
saiba mais!
A partir de agora, você sabe como economizar memória ao utilizar o Lazy. Além disso,
existem outras aplicações do Lazy que podem ser consultadas clicando aqui.
4. REFLECTION (REFLEXÃO)
Em algumas situações, talvez seja interessante, desenvolver métodos que possam trabalhar
com vários tipos de objetos. Agora você deve estar pensando: já discutimos algo relacionado
a este item nos tipos genéricos? Sim, verdade, mas em algumas situações a necessidade pode
O reflection (reflexão) fornece objetos (do tipo Type) que descrevem assemblies, módulos e
tipos. É possível usar a reflexão para criar dinamicamente uma instância de um tipo, associar
o tipo a um objeto existente ou obter o tipo de um objeto existente e invocar seus métodos
ou acessar suas propriedades e campos. Se você estiver usando atributos em seu código,
a reflexão permite acessá-los. A seguir, vamos analisar um exemplo prático da utilização do
reflection.
No exemplo a seguir, temos uma estrutura com três classes, onde as classes Livro e Revista
representam os objetos que podem ser acessados em um programa de leitura, e a classe
RegistrarLog, que possui a responsabilidade de salvar o log de acesso em cada tipo.
• Entre as linhas 24 e 34, estão a estrutura das classes Livro e Revista, com suas propriedades.
• Note que nas linhas 12 e 13, foram instanciados os objetos das classes Livro e Revista. Vale
ressaltar que esta estrutura foi criada apenas para teste, sem uma funcionalidade real.
• Entre as linhas 15 e 21, está a estrutura do método responsável em salvar o log do Livro.
A Figura 20, possui uma estrutura idêntica ao exemplo da Figura 19. Entretanto note que o
método de registrar o log foi alterado. Inicialmente seu nome foi alterado para Registrar. O
parâmetro que ele recebe é do tipo object, que significa que pode receber qualquer tipo de
objeto. Note que na linha 17, foi criado um tipo que recebe o tipo do objeto por meio do obj.
Getype(). Então, neste momento o tipo pode ser um Livro ou Revista. Entre as linhas 21 e 24, é
realizado um foreach para armazenar o nome da propriedade do tipo e o valor. Note que, as
classes podem ter quantidade de propriedades diferentes, então, perceba que esta estrutura
pode controlar qualquer objeto.
saiba mais!
Conheça o Mono.cecil que é uma implementação de código aberto do Framework .NET
Framework da Microsoft baseado nos padrões ECMA para o C# e a Common Language
Runtime. Basta clicar aqui.
Então, vamos desenvolver um exemplo, onde serão apresentadas apenas as classes com a
maioria dos itens relacionados à Programação Orientada Objetos.
DICA DO AUTOR
Se ainda tiver dúvidas sobre objetos e classes, volte ao conteúdo da Aula 1.
Imagine que uma empresa de aluguel de temas para festa infantil te contrate para desenvolver
um controle de locações. Vale ressaltar que, como é apenas um modelo didático, vamos
delimitar o escopo do programa para compreendermos sua estrutura.
A seguir, vamos identificar as classes e os possíveis atributos que serão implementados como
propriedades. Entretanto, seria interessante que você tentasse descobrir as classes antes de
continuar a leitura.
Dentro da área de análise de sistema, existem alguns métodos para realizar a identificação das
classes e seus atributos, entretanto este assunto não será abordado neste momento. Contudo,
vamos utilizar nossa percepção do minimundo que foi relatado, para identificar as classes.
Note que existem algumas palavras que podem nos ajudar a identificar. Inicialmente, pense
em procurar os substantivos, pois eles são fortes candidatos a se tornarem classes.
• Aluguel: note que aluguel possui algumas características que precisam ser controladas,
pense, como saber quantos aluguéis a empresa realizou? Como saber o valor que foi
faturado no mês? Além disso, note que uma festa possui algumas propriedades, como
data, hora de início e fim da festa e valor cobrado.
• Tema: note que para realizar um aluguel é necessário escolher um tema. E este tema possui
características, como nome, valor do aluguel, pois o aluguel da Cinderela pode ser mais
caro do que o aluguel dos Avengers. Além disso, note que durante o texto é descrito sobre
a necessidade de salvar o nome da cor da toalha que será utilizada com o tema.
• Itens: note que para cada tema existem alguns itens que o compõe. Este item pode possuir
nome e descrição. Além disso, a classe tema terá uma composição de itens. Pois não existe
um tema que não tenha pelo menos um item, não é verdade?
• Cliente: note que no texto foi descrito que existem clientes, então existe a necessidade da
criação dessa classe. Além disso, foi citado a necessidade de controlar clientes por tipo
jurídico ou físico. Então, teremos duas subclasses: Fisico e Juridico.
A Figura 21, representa o diagrama de classe do projeto. Perceba que todas as classes foram
criadas. Além disso, criamos uma classe Desconto para simularmos a utilização de métodos
estáticos. A seguir vamos criar um projeto com a estrutura das classes e detalhar cada parte
do código.
Neste momento, sugiro que tente criar o programa em um projeto Windows Forms ou Console
Application. Isto é indispensável para você colocar em prática o que aprendeu.
Então, vamos lá! A partir de agora, vamos apresentar toda a estrutura das classes do diagrama
(Figura 21) e explicar os detalhes e analisar os conceitos de Programação Orientada a Objetos
que foram utilizados.
A Figura 23, representa a estrutura da casse tema. Como foi definido no diagrama de classe
(Figura 21), existe uma relação de composição entre a classe Tema e ItemTema, pois um tema
deve ser composto por um ou mais itens, além disso, o tema não existe sem que tenha pelo
menos um item. Na prática, é possível afirmar que na classe Tema teremos uma lista de itens.
• Nas linhas 11, 12 e 13, foram criadas três propriedades, lembre-se que esta é uma das formas
da linguagem C# encapsular atributos de classe. Mas lembra o que é Encapsulamento?
Encapsulamento pode auxiliar na segurança, pois é possível “esconder” métodos e atributos
de uma classe para que não sejam acessados por classes externas. Isto pode auxiliar na
segurança e integridade dos produtos de software. Note que as propriedades podem ser
lidas (get) por classes externas, porém não podem ser acessadas, pois o set está definido
como privado (private).
• Na linha 16, foi declarado a assinatura do método Salvar. Lembra o que significa a assinatura
de um método? A assinatura do método é definida pela sua estrutura relacionada com os
seguintes itens: nome do método, número de parâmetros, os modificadores dos parâmetros
e os tipos dos parâmetros.
• Entre as linhas 20 e 23, temos a estrutura responsável em adicionar objetos do tipo ItemTema
na lista de itens. Neste momento, utilizamos uma lista genérica de elementos List<T>.
A seguir, vamos analisar as classes Cliente, Fisico e Juridico. Mas antes volte no diagrama de
classe (Figura 21) e veja como essas classes estão inseridas no contexto do diagrama.
O exemplo da Figura 24, representa a classe Cliente. Note que utilizamos alguns conceitos
de programação orientada a objetos. Inicialmente a classe foi declarada como abstrata
(abstract), ou seja, ela não pode ser instanciada por outras classes. E isto seria realmente
necessário neste exemplo, imagine, como temos duas classes Fisico e Juridico que herdam da
classe Cliente, naturalmente durante o desenvolvimento do programa, nunca será necessário
instanciar uma classe Cliente. Neste mesmo exemplo, como a classe é abstrata, seus métodos
obrigatoriamente devem ser abstratos e não podem possuir implementação. A seguir, vamos
analisar as classes Fisico e Juridico que herdam da classe Cliente.
A Figura 25, representa a classe Fisico e Juridico. Antes de entrar nos detalhes do código, pense:
Um cliente jurídico (empresa) possui características distintas de um cliente físico (você), então,
seria interessante ter essas informações separadas, entretanto, os dois tipos também possuem
características idênticas, que no nosso exemplo foi adicionado na classe Cliente (superclasse).
Alguns detalhes sobre o exemplo da Figura 25 podem ser detalhados em:
• Note que nas duas classes, o método Salvar foi sobrescrito (override). Neste momento
estamos atendendo uma obrigação, pois quando uma classe herda de outra classe, e
a classe herdada (superclasse) possui métodos abstratos, é obrigatório que a classe
filha sobrescreva esses métodos. Note no exemplo da Figura 24, que o método Salvar foi
declarado como abstrato na classe Cliente. Além disso, nesse método aplicamos outro
A seguir, vamos analisar as classes Endereco e Aluguel. Mas antes, volte no diagrama de classe
(Figura 21) e análise como essas classes estão inseridas no contexto do diagrama.
A Figura 26, representa a classe Endereco, com suas propriedades. Todas as propriedades
podem ser lidas (get) e alteradas (set) por classe externas.
A Figura 27, representa a estrutura da classe Aluguel. Note que foram criadas 5 propriedades.
Vale destacar que a propriedade endereco (linha 15), será utilizada para instanciar um objeto
do tipo Endereco, como o relacionamento é de um para um, ou seja, um aluguel possui um
endereço, e um endereço pertence a um aluguel, esta seria uma das formas de realizar este
relacionamento.
Vamos descrever sobre a última classe. Mas antes gostaria de saber: você lembra o que é
método estático? Métodos estáticos não requerem uma instância da classe e não podem
acessar de forma implícita os dados. Na linguagem C#, o método estático é definido com o
A Figura 28, representa a classe Desconto que possui dois métodos estáticos. Note que os
métodos são públicos (publics) e possuem o identificador de estáticos (static). Além disso, a
classe também é estática. Então, em qualquer parte do programa, os métodos dessa classe
podem ser utilizados, sem a necessidade de instanciar um objeto (New). Neste exemplo, os
métodos possuem o um retorno do tipo Decimal. E para finalizar, veja que aplicamos o conceito
de sobrecarga de métodos, pois os métodos possuem o mesmo nome, porém com assinaturas
diferentes.
VAMOS PRATICAR?!
Exercício - Com base na estrutura apresentada na revisão, simule
algumas locações, com auxílio de lista e telas windows forms ou
com Console Application. Fique à vontade para aplicar a sua
criatividade, pois neste momento você deve estar preparado(a)
para construir projetos de software orientado a objetos.
RECAPITULANDO
Caro(a) Aluno(a), chegamos ao fim da nossa aula. Espero que tenha compreendido o conteúdo
e resolvido os exercícios. Estudamos sobre Reflection, Lazy, Classes e Métodos Genéricos.
Trabalhamos com serialização e deserialização de objetos. Além disso, realizamos uma revisão
sobre os conceitos e práticas de programação orientada a objetos.
VIDEOAULA
Após a leitura e o estudo do seu livro-texto, chegou o momento de
complementar seu conhecimento. Vá até seu Ambiente Virtual
de Aprendizagem e acesse a Videoaula referente à Aula.
MANZANO, José Augusto N. G. Programação de computadores C#. São Paulo: Érica, 2014.
MELO, Ana Cristina. Exercitando modelagem em UML. Rio de Janeiro: Brasport, 2006.
SHARP, John; MANIEZ, Dominique. Visual C# 2010. Microsoft Press, 2010. Porto Alegre: Bookman,
2011.