julho 31, 2010

Grandes poderes trazem grandes responsabilidades...

Herança é um recurso poderoso oferecido pela orientação a objetos, mas para aproveitar suas vantagens, é preciso ter cuidado e fazer uso consciente dela.

Herança é um relacionamento fortíssimo entre duas classes. Quando você diz que um coisa herda outra em orientação a objetos, você está realmente dizendo que: "uma coisa além de ser uma coisa, também é outra coisa". Ahn?! O Que?! Como assim?! Parece até diálogo do Oráculo com o Neo em Matrix. Calma, um exemplo simples pode desfazer toda a confusão. Se eu digo que:

class Cachorro extends Animal{}

De fato, eu estou dizendo que "Cachorro além de ser um Cachorro, também é um Animal". Na prática, qualquer variável de referência do tipo Animal, pode apontar para um objeto de Cachorro na Heap.

Dizer que Cachorro é um Animal, faz todo sentido, nossa classe Cachorro além de possuir uma interface própria, carrega toda a interface referente à Animal. Herança tem um preço, ela gera acoplamento entre classes, elas se tornam intimamente ligadas, mas neste contexto, é perfeitamente aceitável, pois é natural que Cachorro seja um Animal. Agora pense, se eu disser:

"Cachorro é uma Cafeteira!"

...

Esquisto não?!...mas eu insisto que Cachorro é uma Cafeteira e codifico:

class Cachorro extends Cafeteira{}

Este código vai compilar e rodar perfeitamente. Nós acabamos de criar uma aberração, um cachorro que faz café. Criamos um acoplamento completamente desnecessário e reduzimos significativamente a coesão da classe cachorro. Uma classe coesa é altamente especializada e possui responsabilidades bem definidas, não é o caso do nosso "Cachorro-Cafeteira".

Vamos dizer que eu não esteja satisfeito com o fato de que meu Cachorro só saiba fazer café, e diga o seguinte:

"Cachorro é uma Cafeteira, um Microondas, um Celular e um Grill George Foreman."

Se o cachorro que faz café já é esquisto, isso aí então...

Java só aceita Herança Simples, isto é, uma classe só pode herdar de outra classe e ponto final. Mas se mesmo com Herança simples, podemos criar um cachorro que faz café, imagine o que pode ser feito utilizando Herança múltipla. C++ é um exemplo de linguagem que utiliza este recurso, onde uma classe pode herdar de várias classes. Herança simples, mal utilizada, pode resultar em classes com responsabilidades mal definidas, isso gera um ônus alto para um projeto orientado a objetos, logo, permitir que classes herdem de diversas classes, pode ser fatal em termos de qualidade de software, pois nada impede que se crie um "Frankenstein", apenas o bom senso.

Java oferece o recurso de interfaces. Uma interface é "uma classe 100% abstrata". Uma classe pode implementar diversas interfaces. Por mais que nada impeça que sua classe implemente interfaces totalmente sem sentido, existe uma vantagem nesta abordagem, pois Interfaces, são livres de implementação, isto é, seus métodos são "ocos", é de responsabilidade da classe implementadora prover funcionalidades aos métodos.

Herança é uma ferramenta muito útil, oferecida pelo paradigma orientado a objetos, porém, utilizá-la com coerência, é responsabilidade do desenvolvedor que preza pela boa qualidade do projeto de software. Lembre-se: Grandes poderes trazem grandes responsabilidades!

2 comentários:

Unknown disse...

Se eu estivesse especificando as características de Cachorro como um bulldog, ou chihuahua isso seria a classe folha, que seria uma classe em filhos ou seria a subclasse?

O exemplo de:
"Cachorro é uma Cafeteira, um Microondas, um Celular e um Grill George Foreman."

Eles estariam acima da clase cachorro ou abaixo da classe?

Rafael van Boekel disse...

Olá Maria,

Desculpe a demora!

No exemplo de Bulldog, Chihuahua, etc, estas seriam subclasses (ou classes filhas) de Cachorro, logo estariam abaixo na hierarquia de herança.

No meu exemplo(absurdo), todas as classes, seriam superclasses de Cachorro, logo estariam acima na hierarquia de herança.

Vc pode observar este comportamento, utilizando o teste IS-A.

Por exemplo, podemos dizer 'Bulldog IS-A Cachorro', isto é, 'Bulldog é subclasse(ou filha) de Cachorro'.

Espero ter ajudado!