Existe alguma diferença entre
public class A extends AbstractB implements C
{...}
versus...
public class A extends AbstractB
{...}
abstract class AbstractB implements C
{...}
Entendo que, em ambos os casos, a classe A terminará em conformidade com a interface. No segundo caso, AbstractB
pode fornecer implementação para métodos de interface no C
. Essa é a única diferença?
Se eu não quiser fornecer uma implementação para qualquer um dos métodos de interface em AbstractB
, qual o estilo que eu deveria estar usando ? O uso de um ou de outro tem algum objetivo oculto de 'documentação'?
java
interfaces
abstract-class
c_maker
fonte
fonte
Respostas:
Tudo depende se
AbstractB implements C
semanticamente. Ou seja, se faz sentido semanticamente paraAbstractB
implementarC
, então vá em frente.Se tomarmos exemplos concretos, a diferença semântica se torna clara.
Se A = Cão, AbstratoB = Animal, C = IBark
A única escolha que faz sentido é
Isso não faz sentido, pois isso implica que todos os animais latem.
As outras diferenças entram em jogo se você tiver mais do que apenas
class A
herdarAbstractB
. No # 1 eles não precisam implementar C, no # 2 são todos forçados a implementar C.fonte
Heterotroph
, parece razoávelAnimal
implementarHeterotroph
. Se você espera muitos outros animais latindo e deseja tratá-los da mesma maneira, outra classeBarkingAnimal extends Animal implements IBark
seria o caminho a seguir.Heterotroph
mas graças para a sua entradaA maneira mais fácil de determinar o relacionamento de herança adequado não é examinar as próprias classes, mas o código que chama métodos nessas classes. Em algum lugar do seu código, você tem algo como
AbstractB b = new A();
ouotherObject.addAbstractB(this);
. De qualquer forma, mais tarde você usará essaAbstractB
referência para fazer várias chamadas de método.Nessa situação, você deseja chamar métodos
C
? Se sim, entãoAbstractB
deve implementarC
. Se não, não deveria. Se você não tiver nenhuma situação como essa, não precisará de herança e deve refatorar para usar a composição, pois é muito mais flexível.fonte
Não é uma finalidade de documentação "oculta". Permite converter AbstractB e todas as subclasses em C. Na verdade, existem três estilos.
Eu usaria este se o AbstractB não implementasse C. logicamente. Mesmo que não forneça os métodos, pode ter significado. Tal como o cão estende os implementos animais Wag. Não faz sentido para todos os animais abanar. Observe que essa abordagem não impede realmente o AbstractB de fornecer a implementação.
Eu usaria este se quisesse que todas as subclasses implementassem a interface E faz sentido que todas elas o façam. Como o Beagle estende o AbstractDog implementa o Wag.
Este é redundante, mas pode adicionar clareza.
fonte