Cómo crear una clase que “extiende” dos clases concretas existentes

Sé muy bien que se puede hacer con la ayuda de interfaces y lo he hecho muchas veces. Pero esta vez mi situación es bastante diferente. Tengo class A , class B y necesito crear otra class C que amplíe A y B porque C debería tener ambas funcionalidades y también tener en cuenta que A y B no están interrelacionadas, por lo que ni siquiera puedo decir que A pueda extender la class B

Estoy bastante confundido, ¿qué debo hacer ahora? Sé que no podemos cambiar a Java … pero al menos habría alguna manera posible. Incluso lo más cercano también puede hacer … por favor, ayúdenme.

Agregar más detalles: – La Class B es una API estándar, mientras que la class A es una clase de excepción común que debe ser heredada por todas las clases de excepción.

Pregunta relacionada:

  • ¿Por qué no hay herencia múltiple en Java, pero se permite la implementación de múltiples interfaces? (aunque mi pregunta anterior no es sobre por qué no está permitido).

Esto normalmente se resuelve utilizando la composición del objeto .

Esto también se recomienda en Effective Java, Ítem 16: Favorecer la composición sobre la herencia .

Java restringe a una clase de tener una es una relación con dos clases (no relacionadas). Sin embargo, no restringe que una clase tenga la funcionalidad de dos clases no relacionadas.


 class A { void doAStuff() { System.out.println("A-method"); } } class B { void doBStuff() { System.out.println("B-method"); } } // Wraps an A and a B object. class C { A aObj; B bObj; void doAStuff() { aObj.doAStuff(); } void doBStuff() { bObj.doBStuff(); } } 

(Alternativamente, podría hacer que la class C extends A y solo cree métodos de envoltura para B , pero tenga en cuenta que debería tener sentido decir que C es una A ).


Tengo un patrón de diseño que debe seguirse y para eso es obligatorio ampliar

Esto es, como probablemente sabes completamente imposible. Sin embargo, podría crear clases proxy para A y B que deleguen la funcionalidad en la instancia C Por ejemplo, al agregar estos dos métodos a la clase C anterior:

 class C { // ... public A asAObject() { return new A() { @Override void doAStuff() { C.this.doAStuff(); } }; } public B asBObject() { return new B() { @Override void doBStuff() { C.this.doBStuff(); } }; } } 

http://en.wikipedia.org/wiki/Adapter_pattern

Su problema se resuelve con el patrón adaptador. Volví a revisar el documento wiki, solo para estar seguro 🙂

No es posible extender dos clases, y así heredar la funcionalidad de ambas, en Java. Su alternativa más fácil es “envolver” al menos una de las dos clases. Entonces, en lugar de extender B, puedes tener una instancia de B dentro de C, declarar cada uno de los métodos de B en C y pasarlos. C no “sería” una B, pero parece que solo desea heredar la funcionalidad. Y si eso también es cierto para A, entonces, bueno, deberías usar este patrón para A y B y no extender tampoco.

Hacer uso de la composición. La clase C contendrá una instancia cada una de las clases A y B.

Puede intentar crear la class C que contendrá una instancia de la class A y una de la class B y sus métodos (crear métodos con los mismos nombres que simplemente llamarán a los métodos de A y B ), se llama Composición, otro método opuesto a la herencia. Por supuesto, eso es en caso de que no necesite instanceof para trabajar con esa clase C

Un principio común de oop es “elegir composición sobre herencia”, ya que no se pueden extender 2 clases. Yo sugeriría tener una de esas clases o ambas como miembros de la Clase C. Eso, por supuesto, si eso funciona para lo que estás tratando de hacer.

¿Es posible que pueda crear una nueva clase D y que tanto la clase A como la clase B se hereden de D?

Cambia la forma en que estás pensando. Piensa en las interfaces. Significa que la clase A es en realidad una implementación de la interfaz A ‘y la clase B es una implementación de la interfaz B’. Y realmente desea una clase C que implemente ambas interfaces A ‘y B’. La clase C no necesita extender nada o usar un patrón en particular o lo que sea. Puede extender A y delegar algunos métodos a B, o puede extender B y delegar algunos métodos a A. O puede delegar todos los métodos a A y B – la implementación es su decisión.