¿Son iguales la composición y la herencia? Si quiero implementar el patrón de composición, ¿cómo puedo hacer eso en Java?
java
oop
inheritance
composition
gmhk
fuente
fuente
Respuestas:
Son absolutamente diferentes La herencia es una relación "es-a" . La composición es un "has-a" .
Realiza la composición teniendo una instancia de otra clase
C
como un campo de su clase, en lugar de extenderC
. Un buen ejemplo donde la composición hubiera sido mucho mejor que la herencia esjava.util.Stack
, que actualmente se extiendejava.util.Vector
. Esto ahora se considera un error. Un vector de pila "no es un" ; no se le debe permitir insertar y eliminar elementos arbitrariamente. Debería haber sido composición en su lugar.Desafortunadamente, es demasiado tarde para rectificar este error de diseño, ya que cambiar la jerarquía de herencia ahora rompería la compatibilidad con el código existente. Si hubiera
Stack
utilizado la composición en lugar de la herencia, siempre se puede modificar para usar otra estructura de datos sin violar la API .Recomiendo el libro de Josh Bloch, Effective Java 2nd Edition
Un buen diseño orientado a objetos no se trata de ampliar liberalmente las clases existentes. Su primer instinto debería ser componer en su lugar.
Ver también:
fuente
Composición significa
HAS A
herencia significa
IS A
Example
: El automóvil tiene un motor y el automóvil es un automóvilEn programación esto se representa como:
fuente
:-/
type
campo de TipoEnum
¿Cómo la herencia puede ser peligrosa?
Tomemos un ejemplo
1) Como está claro en el código anterior, la Clase Y tiene un acoplamiento muy fuerte con la clase X. Si algo cambia en la superclase X, Y puede romperse dramáticamente. Supongamos que en el futuro la clase X implementa un método de trabajo con la firma a continuación
El cambio se realiza en la clase X pero hará que la clase Y no sea compatible. Entonces, este tipo de dependencia puede subir a cualquier nivel y puede ser muy peligroso. Cada vez que la superclase puede no tener visibilidad completa para codificar dentro de todas sus subclases y la subclase puede seguir notando todo el tiempo lo que sucede en la superclase. Por lo tanto, debemos evitar este acoplamiento fuerte e innecesario.
¿Cómo resuelve la composición este problema?
Veamos revisando el mismo ejemplo
Aquí estamos creando referencia de clase X en clase Y e invocando método de clase X creando una instancia de clase X. Ahora todo ese fuerte acoplamiento se ha ido. Superclase y subclase son altamente independientes entre sí ahora. Las clases pueden realizar libremente cambios que eran peligrosos en la situación de herencia.
2) Segunda ventaja muy buena de la composición, ya que proporciona flexibilidad para llamar a métodos, por ejemplo:
En la clase de prueba usando la referencia r, puedo invocar métodos de la clase X y de la clase Y. Esta flexibilidad nunca estuvo allí en la herencia
3) Otra gran ventaja: pruebas unitarias
En el ejemplo anterior, si no se conoce el estado de la instancia x, se puede burlar fácilmente utilizando algunos datos de prueba y todos los métodos se pueden probar fácilmente. Esto no era posible en absoluto en la herencia, ya que dependía en gran medida de la superclase para obtener el estado de instancia y ejecutar cualquier método.
4) Otra buena razón por la que debemos evitar la herencia es que Java no admite la herencia múltiple.
Tomemos un ejemplo para entender esto:
Bueno saber :
la composición se logra fácilmente en tiempo de ejecución, mientras que la herencia proporciona sus características en tiempo de compilación
la composición también se conoce como relación HAS-A y la herencia también se conoce como relación IS-A
Por lo tanto, habitúese a preferir siempre la composición sobre la herencia por varias razones anteriores.
fuente
La respuesta dada por @Michael Rodrigues no es correcta (pido disculpas; no puedo comentar directamente), y podría generar cierta confusión.
La implementación de la interfaz es una forma de herencia ... cuando implementa una interfaz, no solo hereda todas las constantes, sino que confirma que su objeto es del tipo especificado por la interfaz; sigue siendo una relación " es-a ". Si un automóvil implementa Rellenable , el automóvil " es un " Rellenable , y puede usarse en su código donde sea que use un Rellenable .
La composición es fundamentalmente diferente de la herencia. Cuando usa la composición, está (como señalan las otras respuestas) haciendo una relación " tiene-a " entre dos objetos, a diferencia de la relación " es-a " que establece cuando usa la herencia .
Entonces, de los ejemplos de autos en las otras preguntas, si quisiera decir que un auto tiene un tanque de gasolina, usaría la composición de la siguiente manera:
Esperemos que eso aclare cualquier malentendido.
fuente
La herencia pone de manifiesto la relación IS-A . La composición resalta la relación HAS-A . El patrón de estrategia explica que la Composición debe usarse en casos en los que hay familias de algoritmos que definen un comportamiento particular.
Ejemplo clásico de una clase de pato que implementa un comportamiento de vuelo.
Por lo tanto, podemos tener múltiples clases que implementan volar, por ejemplo:
Si hubiera sido por herencia, tendríamos dos clases diferentes de aves que implementan la función de volar una y otra vez. Entonces la herencia y la composición son completamente diferentes.
fuente
La composición es tal como suena: crea un objeto conectando partes.
EDITAR el resto de esta respuesta se basa erróneamente en la siguiente premisa.
Esto se logra con las interfaces.
Por ejemplo, usando el
Car
ejemplo anterior,Entonces, con algunos componentes teóricos estándar, puede construir su objeto. Entonces es su trabajo completar cómo
House
protege a sus ocupantes y cómoCar
protege a sus ocupantes.La herencia es como al revés. Comienza con un objeto completo (o semi-completo) y reemplaza o anula los diversos bits que desea cambiar.
Por ejemplo,
MotorVehicle
puede venir con unFuelable
método yDrive
método. Puede dejar el método Fuel como está porque es lo mismo para llenar una moto y un automóvil, pero puede anular elDrive
método porque la Moto conduce de manera muy diferente a aCar
.Con la herencia, algunas clases ya están completamente implementadas, y otras tienen métodos que se ven obligados a anular. Con Composition no se te da nada. (pero puede implementar las interfaces llamando a métodos en otras clases si tiene algo por ahí).
La composición se considera más flexible, porque si tiene un método como iUsesFuel, puede tener un método en otro lugar (otra clase, otro proyecto) que solo se preocupa por tratar con objetos que pueden ser alimentados, independientemente de si es un automóvil, barco, estufa, barbacoa, etc. Las interfaces exigen que las clases que dicen que implementan esa interfaz realmente tengan los métodos de los que se trata esa interfaz. Por ejemplo,
entonces puedes tener un método en otro lugar
Extraño ejemplo, pero muestra que a este método no le importa lo que se está llenando, porque el objeto se implementa
iUsesFuel
, se puede llenar. Fin de la historia.Si usaste Herencia en su lugar, necesitarías diferentes
FillHerUp
métodos para tratarMotorVehicles
yBarbecues
, a menos que tuvieras algún objeto base "ObjectThatUsesFuel" bastante extraño del cual heredar.fuente
ThisCase
, no encamelCase
. Por lo tanto, es mejor nombrar sus interfacesIDrivable
, etc. Es posible que no necesite la "I" si reagrupa todas sus interfaces en un paquete correctamente.No son lo mismo.
Composición : Permite que un grupo de objetos tenga que ser tratado de la misma manera que una sola instancia de un objeto. La intención de un compuesto es "componer" objetos en estructuras de árbol para representar jerarquías de parte completa.
Herencia : una clase hereda campos y métodos de todas sus superclases, ya sean directas o indirectas. Una subclase puede anular los métodos que hereda o puede ocultar los campos o métodos que hereda.
El artículo de Wikipedia es lo suficientemente bueno como para implementar un patrón compuesto en Java.
Participantes clave:
Componente :
Hoja :
Compuesto :
Ejemplo de código para comprender el patrón compuesto :
salida:
Explicación:
Consulte la siguiente pregunta para Pros y Contras de Composición y Herencia.
¿Prefieres la composición a la herencia?
fuente
Como otro ejemplo, considere una clase de automóvil, este sería un buen uso de la composición, un automóvil "tendría" un motor, una transmisión, llantas, asientos, etc. No ampliaría ninguna de esas clases.
fuente
La composición es donde algo se compone de partes distintas y tiene una fuerte relación con esas partes. Si la parte principal muere, también lo hacen los demás, no pueden tener vida propia. Un ejemplo aproximado es el cuerpo humano. Saca el corazón y todas las otras partes mueren.
La herencia es donde simplemente tomas algo que ya existe y lo usas. No hay una relación fuerte. Una persona podría heredar la herencia de su padre, pero puede prescindir de ella.
No conozco Java, así que no puedo proporcionar un ejemplo, pero sí puedo proporcionar una explicación de los conceptos.
fuente
La herencia entre dos clases, donde una clase se extiende a otra, establece la relación " IS A ".
La composición en el otro extremo contiene una instancia de otra clase en su clase que establece la relación " Tiene A ". La composición en Java es útil ya que técnicamente facilita la herencia múltiple.
fuente
En palabras simples, la agregación significa tiene una relación.
La composición es un caso especial de agregación . De una manera más específica, una agregación restringida se llama composición. Cuando un objeto contiene el otro objeto, si el objeto contenido no puede existir sin la existencia del objeto contenedor, entonces se llama composición. Ejemplo: una clase contiene estudiantes. Un estudiante no puede existir sin una clase. Existe composición entre clase y alumnos.
Por qué usar la agregación
Código de reutilización
Cuando usar agregación
La reutilización del código también se logra mejor mediante la agregación cuando no hay un barco de Relación
Herencia
La herencia es una relación padre-hijo La herencia significa es una relación
La herencia en Java es un mecanismo en el cual un objeto adquiere todas las propiedades y comportamientos del objeto padre.
Uso de herencia en Java 1 Code Reusability. 2 Agregue una característica adicional en la clase secundaria, así como la anulación del método (para que se pueda lograr el polimorfismo en tiempo de ejecución).
fuente
Aunque tanto la herencia como la composición proporcionan la reutilización del código, la principal diferencia entre la composición y la herencia en Java es que la composición permite la reutilización del código sin extenderlo, pero para la herencia debe extender la clase para cualquier reutilización de código o funcionalidad. Otra diferencia que surge de este hecho es que al usar Composición puede reutilizar el código incluso para la clase final que no es extensible, pero la Herencia no puede reutilizar el código en tales casos. Además, al usar Composición, puede reutilizar el código de muchas clases, ya que se declaran solo como una variable miembro, pero con Herencia puede reutilizar el código de una sola clase porque en Java solo puede extender una clase, porque la herencia múltiple no es compatible con Java . Sin embargo, puede hacer esto en C ++ porque allí una clase puede extender más de una clase. Por cierto, siempre debesPrefiero la composición a la herencia en Java , no solo soy yo, sino que incluso Joshua Bloch ha sugerido en su libro
fuente
Creo que este ejemplo explica claramente las diferencias entre herencia y composición .
En este ejemplo, el problema se resuelve usando herencia y composición. El autor presta atención al hecho de que; en herencia , un cambio en la superclase podría causar problemas en la clase derivada, que la hereda.
Allí también puede ver la diferencia en la representación cuando usa un UML para herencia o composición.
http://www.javaworld.com/article/2076814/core-java/inheritance-versus-composition--which-one-should-you-choose-.html
fuente
Herencias Vs Composición.
Las herencias y la composición se utilizan tanto para la reutilización como para la extensión del comportamiento de la clase.
Las herencias se usan principalmente en un modelo de programación de algoritmos familiares, como el tipo de relación IS-A, que significa un tipo de objeto similar. Ejemplo.
Estos pertenecen a la familia Car.
La composición representa el tipo de relación HAS-A. Muestra la capacidad de un objeto como Duster tiene cinco engranajes, Safari tiene cuatro engranajes, etc. Siempre que necesitemos ampliar la capacidad de una clase existente, utilice la composición. Ejemplo: necesitamos agregar un engranaje más en el objeto Duster, luego tenemos que crear un objeto de engranaje más y componerlo en el objeto Duster.
No deberíamos hacer los cambios en la clase base hasta / a menos que todas las clases derivadas necesiten esa funcionalidad. Para este escenario deberíamos usar Composición.
clase A derivada por clase B
Clase A Derivada por Clase C
Clase A Derivada por Clase D.
Cuando agregamos cualquier funcionalidad en la clase A, entonces está disponible para todas las subclases, incluso cuando la Clase C y D no requieren esa funcionalidad. Para este escenario, necesitamos crear una clase separada para esa funcionalidad y componerla en la clase requerida ( Aquí está la clase B).
A continuación se muestra el ejemplo:
fuente
Composición significa crear un objeto para una clase que tenga relación con esa clase en particular. Supongamos que el estudiante tiene relación con las cuentas;
Una herencia es que esta es la clase anterior con la característica extendida. Eso significa que esta nueva clase es la clase Old con alguna característica extendida. Supongamos que el estudiante es estudiante pero todos los estudiantes son humanos. Entonces hay una relación con el estudiante y el humano. Esto es herencia.
fuente
No, ambos son diferentes. La composición sigue la relación "HAS-A" y la herencia sigue la relación "IS-A". El mejor ejemplo para la composición fue el patrón estratégico.
fuente
Herencia significa reutilizar la funcionalidad completa de una clase. Aquí mi clase tiene que usar todos los métodos de la superclase y mi clase se unirá a la superclase y el código se duplicará en ambas clases en caso de herencia.
Pero podemos superar todos estos problemas cuando usamos la composición para hablar con otra clase. composición está declarando un atributo de otra clase en mi clase con la que queremos hablar. y qué funcionalidad queremos de esa clase podemos obtener usando ese atributo.
fuente