Software, Java & afins

Fabricio Braga, Sun Certified

Herança, Interface e Classes Abstratas

escrito por Fabricio Braga em Mar 2008

Assunto interessante, e que para muitos desenvolvedores não é muito claro. Porque Java não suporta heranças múltiplas? Quando usar Interface? Quando usar Herança? Quando usar uma Classe Abstrata?

Aqui procurarei explicar o assunto, usando como base minha própria experiência e também algumas referências importantes.

Porque Java não possui Herança Múltipla?

A resposta é simples, se considerarmos os fatores nos quais a linguagem Java se baseia. Neste white paper publicado por James Gosling and Henry McGilton em 1996, segundo eles, Java foi elaborada com foco nos seguintes requisitos:

  • Ser simples, orientada a objeto, e de fácil compreeensão;
  • Robusta e segura;
  • Ter uma arquitetura neutra e ser portável;
  • Ter boa performance;
  • Ser interpretada e dinâmica;

A questão da Herança Múltipla atende ao ponto “ser simples e de fácil compreensão“. Simples assim. Uma linguagem que permitisse Herança Múltipla estaria agregando uma complexidade grande, e James Gosling ao que tudo indica quis fugir ao máximo disso.

Quando usar Interface, Herança e Classe Abstrata?

Em uma entrevista concedida em 1999, James Gosling define as Interfaces como “coisas que conectam peças”, e usa o exemplo de uma torradeira (uma peça), que precisa se conectada na eletricidade (outra peça). O cabo que pluga uma na outra é a Interface. A orientação a objeto em uma linguagem de progamação é como você expressa essas interfaces.

Do ponto de vista do desenvolvedor, a “arte” é visualizar o que uma Interface deve ter e o que ela não deve ter. Em cursos básicos de Java, aprendemos que uma Interface é algo como um contrato – eu mesmo já ensinei isso no passado -, mas hoje acredito que isso dá uma idéia imprecisa do real papel de uma Interface que é na realidade algo mais abrangente e flexível. Hoje minha opinião é de que Interfaces deveriam inclusive ser usadas mesmo em muitos casos onde de forma preguiçosa utilizamos Herança.

Parece exagero? Pois recentemente me deparei com várias pessoas criticando o uso de Herança. Os principais argumentos são: código muito acoplado e quebra de encapsulamento. A explicação é a seguinte: para uma sub-classe ficaria muito difícil funcionar corretamente se ela não conhecesse muito bem o ?odigo da super-classe, certo? Pois bem, se fizermos isso (se a sub-classe passar a conhecer os detalhes da implementação de um comportamento), estaremos então quebrando o encapsulamento.

No livro Effective Java, Joshua Bloch dá alguns exemplos e recomenda o uso de Composição ao invés de Herança – e o p?oprio Gosling faz isso sutilmente em sua entrevista de 1999. Na prática do dia-a-dia, o desenvolvedor acaba usando Herança por preguiça. Na maior parte das vezes poderiamos substituir a Herança preguiçosa por um simples refactoring extraindo os métodos herdados e a criação de uma implementação delegando estes métodos.

Bem, e quanto ? s Classes Abstratas?

Decidir entre Interface ou Classe Abstrata não implica na exclusão da outra. Se o seu design precisa de uma maior flexibilidade você deve usar Interface. De qualquer forma, você também pode usar Classes Abstratas quando precisar prover algum comportamento default.

Classes Abstratas permitem que você pré-defina algum comportamento, mas também é possível a sub-classe definir seus proprios comportamentos. Por exemplo, se você tem um Framework, uma Classe Abstrata poderia prover serviços default para envio de email. Isto permitiria que você os extendesse e usasse na sua aplicação. Entretanto suponha que existe uma determinada situação onde você pode querer um comportamento diferente, tal como usar tipos diferentes de autenticação para o envio. Neste caso, a Classe Abstrata do Framework sabe que precisa destes métodos, mas admite também que não sabe como implementar estes métodos, então ela pode declara-los como abstratos, obrigando a sub-classe a implementa-los da forma que achar melhor.

Este é um caso típico do uso da Classe Abstrata.

Hoje concluo que muitos dizem que conhecem Orientação a Objeto, mas poucos realmente escrevem código usando Orientação a Objeto. Costumo desconfiar de “gurus” e “papas” do Java que ficam escrevendo seus livros e dando suas opiniões por aí, mas nesse caso, fico com a opinião de James Gosling e de Joshua Bloch: evite Heranças, use Interfaces e Composição.

Deixo abaixo algumas referências sobre o assunto:

James Gosling na Wikipedia

Java World, sobre Heranças Múltiplas em Java

A célebre entrevista de 1999

Java World: Classes Abstratas e Interfaces

Comments are closed.