Herança de classe versus herança de interface

É importante compreender a diferença entre a classe de um objeto e seu tipo.

A classe de um objeto define como ele é implementado. A classe define o estado interno do objeto e a implementação de suas operações. Em contraste a isso, o tipo de um objeto se refere somente à sua interface – o conjunto de solicitações às quais ele pode responder. Um objeto pode ter muitos tipos, e objetos de diferentes classes podem ter o mesmo tipo.

Naturamente, existe um forte relacionamento entre classe e tipo. Uma vez que uma classe define as operações que um objeto pode executar, ela também define o tipo do objeto. Quando dizemos que o objeto é uma instância de uma classe, queremos dizer que o objeto suporta a interface definida pela classe.

Linguagens como C++ e Eiffel utilizam classes para especificar tanto o tipo de um objeto como a sua implementação. Os programadores em Smalltalk não declaram os tipos de variáveis; consequentemente, o compilador não verifica se os tipos dos objetos atribuídos a uma variável são subtipos do tipo da variável. Enviar uma mensagem exige a verificação de que a classe do receptor implementa a mensagem, mas não exige a verificação de que o receptor seja uma instância de uma classe específica.

É também importante compreender a diferença entre herança de classe e herança de interface (ou subtipificação). A herança de classe define a implementação de um objeto em termos da implementação de outro objeto. Resumidamente, é um mecanismo para compartilhamento de código e de representação. Diferentemente disso, a herança de interface (ou subtipificação) descreve quando um objeto pode ser usado no lugar do outro.

É fácil confundir esses dois conceitos porque muitas linguagens não fazem uma distinção explícita. Em linguagens como C++ e Eiffel, herança significa tanto a herança de interface como a de implementação. A maneira padrão de herdar uma interface em C++ é herdar publicamente de uma classe que tem apenas funções-membros virtuais. Herança pura de interface assemelha-se em C++ a herdar publicamente de classes abstratas puras. A herança pura de implementação, ou herança de classe, pode ser assemelhada com a herança privada. Em Smalltalk, herança significa somente herança de implementação. Você pode atribuir instâncias de qualquer classe a uma variável, contanto que essas instâncias apoiem a operação executada sobre o valor da variável.

Embora muitas linguagens de programação não apoiem a distinção entre herança de interface e de implementação, as pessoas fazem a distinção na prática. Os programadores Smalltalk usualmente pensam como se as subclasses fossem subtipos (embora existam algumas exceções bem conhecidas); programadores C++ manipulam objetos através de tipos definidos por classes abstratas.

Muitos padrões de projeto dependem desta distinção. Por exemplo, os objetos numa Chain of Responsibility devem ter um tipo em comum, mas usualmente não compartilham uma implementação. No padrão Composite, o Component define uma interface comum. O Command, o Observer, o State e o Strategy são frequentemente implementados com classes abstratas que são puramente interfaces.

Padrões de Projeto: soluções reutilizáveis de software orientado a objetos / Erich Gama, Richard Helm, Ralph Johnson e John Vlissides; trad. Luiz A. Meirelles Salgado. – Porto Alegre: Bookman, 2000

You may also like...