¿Hay alguna diferencia entre
public class A extends AbstractB implements C
{...}
versus...
public class A extends AbstractB
{...}
abstract class AbstractB implements C
{...}
Entiendo que en ambos casos, la clase A terminará conforme a la interfaz. En el segundo caso, AbstractB
puede proporcionar implementación para métodos de interfaz en C
. ¿Es esa la única diferencia?
Si NO deseo de proporcionar una implementación para cualquiera de los métodos de interfaz en AbstractB
, qué estilo debo utilizar ? ¿Usar uno u otro tiene algún propósito oculto de 'documentación'?
java
interfaces
abstract-class
c_maker
fuente
fuente
Respuestas:
Todo depende de si
AbstractB implements C
semánticamente. Es decir, si tiene sentido semánticamente paraAbstractB
implementarC
, entonces adelante.Si tomamos ejemplos concretos, la diferencia semántica se vuelve clara.
Si A = Perro, Resumen B = Animal, C = IBark
La única opción que tiene sentido es
Esto no tiene sentido, ya que esto implicaría que todos los animales ladran.
Las otras diferencias entran en juego si tienes más que solo
class A
heredar deAbstractB
. En el n. ° 1 no necesitan implementar C, en el n. ° 2 todos están obligados a implementar C.fuente
Heterotroph
razonable, parece razonableAnimal
implementarlaHeterotroph
. Si espera muchos otros animales que ladran y quiere tratarlos de la misma manera, otra claseBarkingAnimal extends Animal implements IBark
sería el camino a seguir.Heterotroph
pero gracias por tu aporteLa manera fácil de determinar la relación de herencia adecuada no es mirar las clases en sí mismas, sino el código que llama a los métodos en esas clases. En algún lugar de tu código tienes algo como
AbstractB b = new A();
ootherObject.addAbstractB(this);
. De cualquier manera, luego usa esaAbstractB
referencia para hacer varias llamadas a métodos.En esa situación, ¿vas a querer llamar a métodos de
C
? Si es así, entoncesAbstractB
debe implementarC
. Si no, no debería. Si no tiene situaciones como esa, entonces no necesita herencia, y debe refactorizar para usar la composición en su lugar porque está mucho más suelto.fuente
No es un propósito de documentación "oculta". Le permite emitir AbstractB y todas sus subclases a C. En realidad, hay tres estilos.
Usaría este si AbstractB no implementara lógicamente C. Incluso si no proporciona los métodos, podría tener sentido. Tales como perro extiende implementos animales Wag. No tiene sentido para todos los animales Wag. Tenga en cuenta que este enfoque en realidad no impide que AbstractB proporcione la implementación.
Usaría este si quisiera que todas las subclases implementen la interfaz Y tiene sentido que todos lo hagan. Tal como Beagle extiende AbstractDog implementa Wag.
Este es redundante pero podría agregar claridad.
fuente