C# - Aplicando conceitos OOP e Polimorfismo na prática
Hoje vamos aplicar conceitos do paradigma da orientação a objetos e polimorfismo em uma aplicação prática. |
A melhor forma de aprender os conceitos de uma linguagem de programação é aplicar os conceitos em uma aplicação prática.
Neste artigo vamos criar uma aplicação para calcular a área de figuras geométricas aplicando conceitos importantes da programação orientada a objetos(POO) como : encapsulamento, herança e polimorfismo, os 3 principais pilares do paradigma da POO.
Se você não conhece nada sobre esses conceitos acompanhe os artigos abaixo publicados sobre o assuto:
Vamos criar uma aplicação Console chamada CalcAreaPOO usando o VS 2017 Community para calcular a área do quadrado, retângulo, triângulo e círculo aplicando os conceitos da POO.
Existem muitas maneiras de implementar o cálculo dessas figuras geométricas e vamos usar uma abordagem a mais simples e aderente ás boas práticas e ao paradigma da POO.
O primeiro conceito que vamos usar será a herança e para isso vamos iniciar criando uma classe abstrata onde vamos definir uma propriedade abstrata chamado CalcularArea que vai retornar o valor da área :
Observe que não definimos o acessor set; pois a área é somente leitura e não pode ser definda pelo usuário.
Poderíamos ter usado uma interface IForma e o resultado final seria o mesmo, mas usar uma classe abstrata neste contexto pode nos dar a opção de fornecer uma implementação padrão para um novo método:
A classe abstrata será a classe base a partir da qual iremos herdar e realizar a implementação da propriedade CalcularArea para cada figura geométrica para qual desejamos calcular a área.
Além disso temos as seguintes diferenças entre Classe Abstrata e Interface:
1 -Classes
abstratas podem ter constantes, membros, stubs de métodos (métodos sem
um corpo) e métodos definidos, enquanto interfaces só podem ter stubs
de constantes e métodos.
2- Métodos e membros de uma classe abstrata podem ser definidos com qualquer
visibilidade, enquanto todos os métodos de uma interface devem ser definidos
como públicos (eles são definidos por padrão).
3- Ao herdar uma classe abstrata, uma classe filha concreta deve definir os
métodos abstratos, enquanto que uma classe abstrata pode estender outra classe
abstrata e os métodos abstratos da classe pai não precisam ser definidos.
4- Da mesma forma, uma interface que estende outra interface não é responsável
pela implementação de métodos da interface pai. Isso ocorre porque as interfaces
não podem definir nenhuma implementação.
5- Uma classe filha só pode estender uma única classe (abstrata ou concreta),
enquanto uma interface pode se estender ou uma classe pode implementar várias
outras interfaces.
6- Uma classe filha pode definir métodos abstratos com a mesma visibilidade, ou
menos restritiva, enquanto uma classe que implementa uma interface deve definir
os métodos com exatamente a mesma visibilidade (pública).
Agora a próxima tarefa será criar classes concretas que herdam da classe abstrata Forma e implemente a propriedade CalcularArea:
1- Classe Quadrado
2- Classe Retângulo
3- Classe Triângulo
4- Classe Círculo
Em todas as implementações estamos herdando a classe abstrata Forma e sobrescrevendo a propriedade CalcularArea para retornar o valor da área da respectiva forma.
Usando propriedades estamos encapsulando o nosso código e podemos incluir lógica extra nos get/set sem quebrar o código; temos ainda o recurso do data binding disponível se precisarmos dele.
A implementação de CalcularArea usa o recurso Expression Bodied Member que usa expressões lambdas tornando o código mais conciso e legível.
Estamos aplicando o conceito de polimorfismo de herança onde Polimorfismo significa muitas formas , na orientação a objetos você pode enviar uma mesma mensagem para diferentes objetos e fazê-los responder da maneira correta.
Você pode
enviar a mensagem CalcularArea para cada objeto
semelhante a uma forma e cada objeto vai se comportar de maneira
diferente para atender a sua solicitação. No caso calculando a área da
respectiva figura.
Quando uma mesma mensagem pode ser processada de diferentes formas temos um exemplo de polimorfismo.
Implementando a interface da aplicação Console
Vamos agora implementar a interface da aplicação Console adotando princípios de boa prática de programação.
Vamos criar um menu de opções onde o usuário escolhe a forma para qual deseja calcular a área. O Fluxo será o seguinte:
No arquivo Program.cs inicialmente vamos definir uma enumeração para representar as opções do menu da nossa aplicação :
A seguir no método Main() vamos usar a enumeração para apresentar o menu e obter a escolha do usuário realizando o cálculo e exibição da área da figura selecionada:
Abaixo temos o código do método GetEscolha() que exibe as opções e processa a escolha do usuário:
A seguir temos o código do método GetDouble() que recebe a entrada do usuário e a converte para double verificando se é um valor válido:
A seguire temos o código das classes para criar cada uma das figuras conforme a escolha do usuário. A implementação solicita a informação do usuário para os dados necessários para calcular a área:
Todos as classes definidas acima retornam uma classe do tipo escolhido pelo usuário.
Executando o projeto iremos obter o resultado é exibido abaixo:
Temos assim um exemplo de aplicação onde aplicamos os recursos de herança, polimorfismos e encapsulamento de forma a termos um código legível e fácil de manter.
É claro que o código pode ser melhorado mas chegamos a um resultado final bem ajustado.
Pegue o projeto aqui : CalcAreaPOO.zip
"Jesus
respondeu: Na verdade, na verdade te digo que aquele que não nascer da água e do
Espírito, não pode entrar no reino de Deus."
João 3:5
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizagens e vídeo aulas para C#
Curso Fundamentos da Programação Orientada a Objetos com VB .NET
NET - Generics - Macoratti
C# - Revendo conceitos sobre Generics - Macoratti
C# - Usando Generics (revisitado) - Macoratti
Usando Generics - Macoratti
C# - Criando e usando uma classe ou método Genérico - Macoratti
Usando Generics - Vinculando dados a um DataGridView ... - Macoratti