Pregunta

He oído que hay una manera de engañar a la herencia única e implementar la herencia múltiple en Java.¿Alguien sabe cómo implementar esto (sin usar la interfaz)?

Solo por curiosidad ;-)

¿Fue útil?

Solución

Claro que puedes, pero es complicado y realmente deberías considerar si ese es el camino que quieres seguir.
La idea es utilizar una herencia basada en alcance junto con una basada en tipos.Lo cual es un lenguaje tipográfico para decir que para propósitos internos, las clases internas "heredan" métodos y campos de la clase externa.Es un poco como mixins, donde la clase externa se mezcla con la clase interna, pero no es tan seguro, ya que puedes cambiar el estado de la clase externa así como usar sus métodos.
Gilad Bracha (uno de los principales diseñadores del lenguaje Java) escribió un papel discutiendo eso.Entonces, supongamos que desea compartir algunos métodos para uso interno entre algunas clases no relacionadas (por ejemplo, para manipulación de cadenas), puede crear subclases de ellas como clases internas de una clase que tenga todos los métodos necesarios, y las subclases podrían usar métodos tanto de sus superclases como de la clase externa.

De todos modos, es complicado para clases complejas y puede obtener la mayor parte de la funcionalidad utilizando importaciones estáticas (a partir de Java 5).Sin embargo, es una gran pregunta para entrevistas de trabajo y concursos de pub ;-)

Otros consejos

SolteroJava no admite la herencia múltiple, sino que tiene interfaces para cumplir el mismo propósito.En caso de que sea inflexible en el uso de herencia múltiple, debe hacerlo en C++.

El uso de la composición en lugar de la herencia tiende a ser la solución a este problema.En realidad, esto también ayuda mucho con la capacidad de prueba, por lo que es una buena práctica en general.

Sin embargo, si sólo desea que su tipo "se comporte" como otros tipos, puede heredar de tantas interfaces como desee;Sin embargo, obviamente no se pueden "tomar prestados" detalles de implementación de estos.

Creo que la razón fundamental por la que Java no admite la herencia múltiple es la misma que C#;Todos los objetos se derivan en última instancia de Object y tener múltiples rutas a la misma clase base es ambiguo para el compilador.Ambiguo == Malo, entonces el compilador no lo permite.

En su lugar, puede simular la herencia múltiple mediante delegación.Ver Este artículo para un ejemplo.

Puedes engañarlo un poco (y lo enfatizo un poco) usando instancias java.lang.reflect.Proxy.

En realidad, esto solo le permite agregar interfaces adicionales y delegar sus llamadas a otra instancia en tiempo de ejecución.

Como alguien que asesora y enseña a nuevos desarrolladores, me horrorizaría si alguien me mostrara un código que hiciera esto.Reflection es una de esas herramientas que realmente necesitas entender y tener un buen conocimiento de Java antes de lanzarte a usarla.Personalmente, solo he hecho esto una vez, y fue para crear un código sobre el que no tenía control, implementar algunas interfaces, esperaba otro código sobre el que no tenía control (fue un truco rápido, por lo que no tuve que escribir y mantener demasiado código de pegamento).

Usar interfaces.Puedes implementar tantos como quieras.Generalmente puedes utilizar alguna variante en el Patrón compuesto (GoF) para poder reutilizar el código de implementación si eso es deseable.

Debe tener cuidado de distinguir la herencia de interfaz (esencialmente herencia de un contrato para proporcionar instalaciones particulares) de la herencia de implementación (herencia de mecanismos de implementación).

Java proporciona herencia de interfaz mediante implementos mecanismo y tu poder tener herencia de interfaz múltiple.

La herencia de implementación es la se extiende mecanismo y sólo tienes una única versión de eso.Tú en realidad ¿Necesita herencia de implementación múltiple?Apuesto a que no, está repleto de consecuencias desagradables, a menos que seas un programador de Eiffel.

Probablemente podría "simularlo" administrando el conjunto de superclases explícitamente y usando la reflexión para buscar en todas las superclases el método de destino.No me gustaría hacer esto en producción, pero podría ser un programa de juguetes interesante.Probablemente podrías hacer muchas cosas raras aprovechando la reflexión, creando clases sobre la marcha e invocando el compilador mediante programación.

JAVA no admite herencia múltiple.

Puede lograr que implemente múltiples interfaces y algunos ven esto como una solución al problema.Personalmente todavía tengo que utilizar la herencia múltiple, por lo que realmente no puedo entender su atractivo.

Normalmente, cuando alguien sugiere herencia múltiple dentro de C# o JAVA, se debe al hecho de que "podrían" en C++.Soy fanático de "sólo porque puedas no significa que debas hacerlo".Como c# y JAVA no lo admiten, ¿por qué intentar forzarlo a hacer algo para lo que no fue diseñado?Esto no quiere decir que haya casos únicos en los que sea una técnica válida, simplemente el código generalmente se puede refactorizar para que no sea necesario.

Estaba pensando en esto un poco más y me di cuenta de que si bien los proxies dinámicos funcionarán (así es como funciona RMI (¿usado?)), si realmente quieres este tipo de funcionalidad, sería mejor que miraras la programación orientada a aspectos (AOP) usando algo como AspectJ (eclipse.org/aspectj).

De esta manera puedes incluir varios aspectos diferentes en una clase, proporcionándote una herencia pseudomixin, sin las horriblemente frágiles jerarquías de herencia.

Como todos los demás han señalado, querer/necesitar herencia múltiple generalmente indica que no estás abordando el problema desde la perspectiva correcta.¡Para empezar, recuerde el principio del GoF de "preferir la composición a la herencia"!

Hubo un esfuerzo por incorporar mixins a Java.Mira este enlace: http://www.disi.unige.it/person/LagorioG/jam/

Al usar clases internas, esto es lo que a veces también prefiere C++: Idioma de clase interna.

Sí, puedes decir que es un truco y es muy interesante. No puedes heredar varias clases en una sola clase, pero es posible implementar múltiples interfaces en una clase como

public class parents implements first, second{

}

pero recuerda, debes anular los métodos declarados en las interfaces.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top