C# - Herança ou Composição ?
Hoje vamos tentar responder à pergunta : "Devo usar herança ou composição ?" |
Herança e composição são duas técnicas de programação usadas para estabelecer relacionamentos entre classes e objetos. Enquanto a herança deriva uma classe de outra, a composição define uma classe como a soma de suas partes.
As classes e objetos criados por herança são
fortemente acoplados porque alterar a classe base ou classe pai
em um relacionamento de herança corre o risco de quebrar seu código.
As classes e objetos criados por meio da composição são fracamente acoplados, o que significa que você pode alterar mais facilmente as partes do componente sem quebrar seu código.
Em geral usar composição traz mais vantagens do que utilizar herança. Os projetos tendem a ser mais simples e reutilizáveis em se favorecendo a composição ao invés da herança.
Como o código fracamente acoplado oferece mais flexibilidade, muitos desenvolvedores aprenderam que a composição é uma técnica melhor que a herança, mas a realidade não é tão simples assim e existem muitos cenários e fatores que atuam de forma que escolher entre herança e composição não é tão simples.
Quando devo usar herança ?
Na programação orientada a objetos, podemos usar a herança quando sabemos que existe um relacionamento do tipo "é um" entre uma classe filha e sua classe pai.
Exemplos:
Em cada exemplo, temos o filho ou subclasse é uma versão especializada do pai ou superclasse. Herdar de uma classe pai é um exemplo de reutilização de código.
Vejamos um exemplo onde carro herda de um veículo:
1- Classe Pai ou classe base
1- Classe Filha ou subclasse
Agora vamos criar uma instância da classe derivada e ver a herança
funcionando:
Abaixo temos o resultado:
Então, quando você considerar usar herança pergunte a sim mesmo se a classe filha realmente é uma versão mais especializada da classe pai.
No exemplo temos que um carro é um tipo de veículo , assim o relacionamento de herança faz sentido.
Mas considere que quando você usa herança você esta tendo os seguintes problemas:
1- Ao usar
herança estamos violando um dos pilares da orientação a objetos: o
encapsulamento, visto que os detalhes da implementação da classe Pai são
expostos nas classes Filhas;
2- Ao usar herança estamos violando um dos princípios básicos das boas
práticas de programação : manter o acoplamento entre as classe fraco,
visto que as classes filhas estão fortemente acopladas à classe Pai e
alterar uma classe Pai pode afetar todas as classes Filhas;
3- As implementações herdadas da classe Pai pelas classes Filhas não
pode ser alteradas em tempo de execução;
Quando devo usar Composição ?
Na programação orientada a objetos, podemos usar a composição nos casos em que um objeto "possui" (ou faz parte de) outro objeto. Alguns exemplos seriam:
Para entender melhor esse tipo de relacionamento, considere a composição de uma casa:
1- A classe pai
A seguir temos o código das classes Quarto , Cozinha e Banheiro que compõe a classe Casa :
Nesse caso, sabemos que uma casa tem um quarto, uma cozinha e um banheiro, e, assim podemos usar os objetos das classes Quarto, Cozinha e Banheiro na composição de uma casa.
Agora mostrando um exemplo de uso teremos:
Com o seguinte resultado:
Assim na composição temos que :
1- Os
objetos que foram instanciados e estão contidos na classe que os
instanciou são acessados somente através de sua interface;
2- A composição pode ser definida dinamicamente em tempo de execução
pela obtenção de referência de objetos a objetos de do mesmo tipo;
3- A composição apresenta uma menor dependência de implementações;
4- Na composição temos cada classe focada em apenas uma tarefa
(princípio SRP);
5- Na composição temos um bom encapsulamento visto que os detalhes
internos dos objetos instanciados não são visíveis;
Mas então
eu nunca devo usar herança ???
(Nunca é uma palavra que nós mortais deveríamos pronunciar com muito
cuidado....)
Então , considere a utilização da herança se...:
- A classe
Filha expressar "um tipo especial de" e não "ser um papel desempenhado
por";
- Uma instância de uma classe Filha NUNCA precisar tornar-se um objeto
de outra classe;
- A classe filha estender ao invés de substituir total ou parcialmente
as responsabilidades da classe Pai;
- A sua hierarquia de herança representar um relacionamento
"É um";
- Você desejar ou precisar realizar alterações globais para
as suas classes filhas alterando uma classe Pai;
- Você precisar aplicar a mesma classe e métodos a diferente tipos de
dados;
E estamos conversados...
Pegue o projeto completo aqui: CShp_HerancaComposicao.zip
Disse Jesus:
"Se, pois, o Filho vos libertar, verdadeiramente sereis livres."
João 8:36
Referências: