La composition et l'héritage sont-ils les mêmes? Si je veux implémenter le modèle de composition, comment puis-je le faire en Java?
208
La composition et l'héritage sont-ils les mêmes? Si je veux implémenter le modèle de composition, comment puis-je le faire en Java?
Réponses:
Ils sont absolument différents. L'héritage est une relation «est-une» . La composition est un "has-a" .
Vous faites de la composition en ayant une instance d'une autre classe
C
comme champ de votre classe, au lieu de l'étendreC
. Un bon exemple où la composition aurait été bien meilleure que l'héritagejava.util.Stack
, qui s'étend actuellementjava.util.Vector
. Ceci est maintenant considéré comme une erreur. Un vecteur de pile "n'est-PAS-un" ; vous ne devez pas être autorisé à insérer et à supprimer des éléments arbitrairement. Cela aurait dû être de la composition à la place.Malheureusement, il est trop tard pour corriger cette erreur de conception, car la modification de la hiérarchie d'héritage romprait maintenant la compatibilité avec le code existant. Si la
Stack
composition avait été utilisée au lieu de l'héritage, elle peut toujours être modifiée pour utiliser une autre structure de données sans violer l'API .Je recommande fortement le livre de Josh Bloch Effective Java 2nd Edition
Une bonne conception orientée objet ne consiste pas à étendre généreusement les classes existantes. Votre premier instinct devrait être de composer à la place.
Voir également:
la source
Composition signifie
HAS A
Héritage signifie
IS A
Example
: La voiture a un moteur et la voiture est une automobileDans la programmation, cela est représenté comme:
la source
:-/
type
champ de typeEnum
Comment l'héritage peut-il être dangereux?
Prenons un exemple
1) Comme indiqué dans le code ci-dessus, la classe Y a un couplage très fort avec la classe X. Si quelque chose change dans la superclasse X, Y peut se briser de façon spectaculaire. Supposons qu'à l'avenir, la classe X implémente un travail de méthode avec la signature ci-dessous
Le changement se fait en classe X mais cela rendra la classe Y incompilable. Ce type de dépendance peut donc atteindre n'importe quel niveau et peut être très dangereux. Chaque fois que la superclasse peut ne pas avoir une visibilité complète pour coder dans toutes ses sous-classes et la sous-classe peut continuer à remarquer ce qui se passe dans la superclasse tout le temps. Nous devons donc éviter ce couplage fort et inutile.
Comment la composition résout-elle ce problème?
Voyons en révisant le même exemple
Ici, nous créons la référence de la classe X dans la classe Y et invoquons la méthode de la classe X en créant une instance de la classe X. Maintenant, tout ce couplage fort a disparu. La superclasse et la sous-classe sont désormais très indépendantes l'une de l'autre. Les classes peuvent librement apporter des modifications dangereuses en situation successorale.
2) Deuxième très bon avantage de la composition en ce qu'elle offre une flexibilité d'appel de méthode, par exemple:
Dans la classe Test en utilisant la référence r, je peux invoquer des méthodes de classe X ainsi que de classe Y. Cette flexibilité n'a jamais été là dans l'héritage
3) Un autre grand avantage: les tests unitaires
Dans l'exemple ci-dessus, si l'état de l'instance x n'est pas connu, il peut facilement être simulé en utilisant certaines données de test et toutes les méthodes peuvent être facilement testées. Cela n'était pas possible du tout en héritage car vous dépendiez fortement de la superclasse pour obtenir l'état d'instance et exécuter n'importe quelle méthode.
4) Une autre bonne raison pour laquelle nous devrions éviter l'héritage est que Java ne prend pas en charge l'héritage multiple.
Prenons un exemple pour comprendre ceci:
Bon à savoir :
la composition est facilement réalisée au moment de l'exécution tandis que l'héritage fournit ses fonctionnalités au moment de la compilation
la composition est également connue sous le nom de relation HAS-A et l'héritage est également connu sous le nom de relation IS-A
Prenez donc l'habitude de toujours préférer la composition à l'héritage pour diverses raisons ci-dessus.
la source
La réponse donnée par @Michael Rodrigues n'est pas correcte (je m'excuse, je ne suis pas en mesure de commenter directement), et pourrait conduire à une certaine confusion.
L'implémentation d' une interface est une forme d'héritage ... lorsque vous implémentez une interface, vous héritez non seulement de toutes les constantes, vous engagez votre objet à être du type spécifié par l'interface; c'est toujours une relation « est-un ». Si une voiture implémente Fillable , la voiture " est un " Fillable , et peut être utilisée dans votre code partout où vous utiliseriez un Fillable .
La composition est fondamentalement différente de l'héritage. Lorsque vous utilisez la composition, vous établissez (comme le notent les autres réponses) une relation " has-a " entre deux objets, par opposition à la relation " is-a " que vous établissez lorsque vous utilisez l'héritage .
Donc, à partir des exemples de voitures dans les autres questions, si je voulais dire qu'une voiture a un réservoir d'essence, j'utiliserais la composition comme suit:
Espérons que cela dissipe tout malentendu.
la source
L'héritage fait ressortir IS-A relation . La composition fait ressortir la relation HAS-A . Le modèle de stratégie explique que la composition doit être utilisée dans les cas où il existe des familles d'algorithmes définissant un comportement particulier.
Exemple classique étant d'une classe de canard qui met en œuvre un comportement de vol.
Ainsi, nous pouvons avoir plusieurs classes qui implémentent le vol, par exemple:
S'il avait été question d'héritage, nous aurions deux classes d'oiseaux différentes qui implémentent la fonction mouche à maintes reprises. L'héritage et la composition sont donc complètement différents.
la source
La composition est exactement comme elle sonne - vous créez un objet en branchant des parties.
MODIFIER le reste de cette réponse est basé à tort sur la prémisse suivante.
Ceci est accompli avec des interfaces.
Par exemple, en utilisant l'
Car
exemple ci-dessus,Ainsi, avec quelques composants théoriques standard, vous pouvez construire votre objet. C'est alors à vous de déterminer comment a
House
protège ses occupants et comment aCar
protège ses occupants.L'héritage est comme l'inverse. Vous commencez avec un objet complet (ou semi-complet) et vous remplacez ou remplacez les différents bits que vous souhaitez modifier.
Par exemple,
MotorVehicle
peut venir avec uneFuelable
méthode et uneDrive
méthode. Vous pouvez laisser la méthode Fuel telle quelle, car c'est la même chose pour remplir une moto et une voiture, mais vous pouvez remplacer laDrive
méthode parce que la moto roule très différemment d'une aCar
.Avec l'héritage, certaines classes sont déjà complètement implémentées, et d'autres ont des méthodes que vous êtes obligé de remplacer. Avec Composition, rien ne vous est donné. (mais vous pouvez implémenter les interfaces en appelant des méthodes dans d'autres classes s'il vous arrive d'avoir quelque chose autour).
La composition est considérée comme plus flexible, car si vous avez une méthode telle que iUsesFuel, vous pouvez avoir une méthode ailleurs (une autre classe, un autre projet) qui se soucie simplement de traiter avec des objets pouvant être alimentés, qu'il s'agisse d'une voiture, bateau, poêle, barbecue, etc. Les interfaces exigent que les classes qui disent qu'elles implémentent cette interface aient en fait les méthodes dont il s'agit. Par exemple,
alors vous pouvez avoir une méthode ailleurs
Exemple étrange, mais cela montre que cette méthode ne se soucie pas de ce qu'elle remplit, car l'objet implémente
iUsesFuel
, il peut être rempli. Fin de l'histoire.Si vous utilisiez l'héritage à la place, vous auriez besoin de différentes
FillHerUp
méthodes pour traiterMotorVehicles
etBarbecues
, sauf si vous aviez un objet de base "ObjectThatUsesFuel" plutôt étrange dont vous devez hériter.la source
ThisCase
, et non encamelCase
. Par conséquent, il est préférable de nommer vos interfacesIDrivable
, etc. Vous pourriez ne pas avoir besoin du «I» si vous regroupez correctement toutes vos interfaces dans un package.Ce ne sont pas les mêmes.
Composition : il permet de traiter un groupe d'objets de la même manière qu'une seule instance d'un objet. L'intention d'un composite est de "composer" des objets en structures arborescentes pour représenter des hiérarchies partielles
Héritage : une classe hérite des champs et des méthodes de toutes ses superclasses, directes ou indirectes. Une sous-classe peut remplacer les méthodes dont elle hérite ou masquer les champs ou les méthodes dont elle hérite.
L' article de Wikipédia est assez bon pour implémenter un modèle composite en java.
Participants clés:
Composant :
Feuille :
Composite :
Exemple de code pour comprendre le modèle composite :
production:
Explication:
Référez-vous à la question ci-dessous pour les avantages et les inconvénients de la composition et de l'héritage.
Vous préférez la composition à l'héritage?
la source
comme autre exemple, considérons une classe de voitures, ce serait une bonne utilisation de la composition, une voiture "aurait" un moteur, une transmission, des pneus, des sièges, etc. Cela ne prolongerait aucune de ces classes.
la source
La composition est l'endroit où quelque chose est composé de parties distinctes et il a une relation forte avec ces parties. Si la partie principale décède, les autres ne peuvent pas avoir leur propre vie. Un exemple grossier est le corps humain. Retirez le cœur et toutes les autres parties disparaissent.
L'héritage est l'endroit où vous prenez simplement quelque chose qui existe déjà et que vous l'utilisez. Il n'y a pas de relation solide. Une personne peut hériter de la succession de son père, mais elle peut s'en passer.
Je ne connais pas Java donc je ne peux pas donner d'exemple mais je peux donner une explication des concepts.
la source
L'héritage entre deux classes, où une classe étend une autre classe établit une relation " EST A ".
La composition à l'autre extrémité contient une instance d'une autre classe dans votre classe établit une relation " A une ". La composition en java est utile car elle facilite techniquement l'héritage multiple.
la source
Dans Simple Word, l'agrégation de mots signifie a une relation.
La composition est un cas particulier d'agrégation . De manière plus spécifique, une agrégation restreinte est appelée composition. Lorsqu'un objet contient l'autre objet, si l'objet contenu ne peut pas exister sans l'existence d'un objet conteneur, il est appelé composition. Exemple: une classe contient des élèves. Un étudiant ne peut pas exister sans classe. Il existe une composition entre la classe et les étudiants.
Pourquoi utiliser l'agrégation
Réutilisation du code
Quand utiliser l'agrégation
La réutilisation du code est également mieux réalisée par agrégation lorsqu'il n'y a pas de navire de relation
Héritage
L'héritage est une relation parent-enfant signifie que l'héritage est une relation
L'héritage en java est un mécanisme dans lequel un objet acquiert toutes les propriétés et les comportements de l'objet parent.
Utilisation de l'héritage dans Java 1 Code Reusability. 2 Ajoutez une fonctionnalité supplémentaire dans la classe enfant ainsi que la substitution de méthode (afin que le polymorphisme d'exécution puisse être atteint).
la source
Bien que l'héritage et la composition fournissent la réutilisation du code, la principale différence entre la composition et l'héritage en Java est que la composition permet la réutilisation du code sans l'étendre, mais pour l'héritage, vous devez étendre la classe pour toute réutilisation du code ou des fonctionnalités. Une autre différence qui vient de ce fait est qu'en utilisant Composition, vous pouvez réutiliser du code même pour la classe finale qui n'est pas extensible, mais l'héritage ne peut pas réutiliser le code dans de tels cas. De plus, en utilisant Composition, vous pouvez réutiliser le code de nombreuses classes car elles sont déclarées comme une simple variable membre, mais avec l'héritage, vous pouvez réutiliser le code sous une seule classe car en Java, vous ne pouvez étendre qu'une seule classe, car l'héritage multiple n'est pas pris en charge en Java . Vous pouvez le faire en C ++ car une classe peut étendre plusieurs classes. BTW, vous devriez toujourspréfèrent la composition à l'héritage en Java , ce n'est pas seulement moi, mais même Joshua Bloch l' a suggéré dans son livre
la source
Je pense que cet exemple explique clairement les différences entre l' héritage et la composition .
Dans cet exemple, le problème est résolu en utilisant l'héritage et la composition. L'auteur fait attention au fait que; dans l' héritage , un changement de superclasse peut provoquer des problèmes dans la classe dérivée, qui l'hérite.
Là, vous pouvez également voir la différence de représentation lorsque vous utilisez un UML pour l'héritage ou la composition.
http://www.javaworld.com/article/2076814/core-java/inheritance-versus-composition--which-one-should-you-choose-.html
la source
Héritages Vs Composition.
Les héritages et la composition sont tous deux utilisés pour la réutilisation et l'extension du comportement de classe.
Les héritages principalement utilisés dans un modèle de programmation d'algorithmes familiaux tels que le type de relation IS-A signifient un type d'objet similaire. Exemple.
Ils appartiennent à la famille Car.
La composition représente le type de relation HAS-A. Elle montre la capacité d'un objet tel que Duster a cinq vitesses, Safari a quatre vitesses, etc. Chaque fois que nous devons étendre la capacité d'une classe existante, utilisez la composition. Exemple, nous devons ajouter un autre engrenage dans l'objet Duster, puis nous devons créer un autre objet engrenage et le composer dans l'objet Duster.
Nous ne devons pas apporter de modifications à la classe de base tant que / à moins que toutes les classes dérivées n'aient besoin de ces fonctionnalités. Pour ce scénario, nous devons utiliser Composition.
classe A dérivée de la classe B
Classe A dérivée de la classe C
Classe A dérivée de la classe D.
Lorsque nous ajoutons une fonctionnalité dans la classe A, elle est disponible pour toutes les sous-classes même lorsque les classes C et D ne nécessitent pas ces fonctionnalités.Pour ce scénario, nous devons créer une classe distincte pour ces fonctionnalités et la composer dans la classe requise ( voici la classe B).
Voici l'exemple:
la source
La composition signifie créer un objet à une classe qui a une relation avec cette classe particulière. Supposons que l'étudiant ait une relation avec les comptes;
Un héritage est, c'est la classe précédente avec la fonctionnalité étendue. Cela signifie que cette nouvelle classe est l'ancienne classe avec des fonctionnalités étendues. Supposons que l'étudiant soit étudiant mais que tous les étudiants soient humains. Il y a donc une relation avec l'étudiant et l'humain. C'est l'héritage.
la source
Non, les deux sont différents. La composition suit la relation "HAS-A" et l'héritage suit la relation "IS-A". Le meilleur exemple de composition était le modèle stratégique.
la source
L'héritage signifie la réutilisation de la fonctionnalité complète d'une classe, ici ma classe doit utiliser toutes les méthodes de la super classe et ma classe sera couplée de manière titrée avec la super classe et le code sera dupliqué dans les deux classes en cas d'héritage.
Mais nous pouvons surmonter tous ces problèmes lorsque nous utilisons la composition pour parler avec une autre classe. composition déclare un attribut d'une autre classe dans ma classe à laquelle nous voulons parler. et quelle fonctionnalité nous voulons de cette classe, nous pouvons obtenir en utilisant cet attribut.
la source