Différence entre L'héritage et la Composition
la Composition et L'héritage sont-ils les mêmes? Si je veux implémenter le pattern de composition, Comment puis-je le faire en Java?
17 réponses
ils sont absolument différents. L'héritage est une " est-une relation. La Composition est un "a-un" .
vous faites la composition en ayant une instance d'une autre classe C
comme champ de votre classe, au lieu d'étendre C
. Un bon exemple où la composition aurait été beaucoup mieux que l'héritage est java.util.Stack
, qui s'étend actuellement java.util.Vector
. Ce qui est maintenant considéré comme une faute. Un pile "est-PAS-un" vecteur; vous ne devriez pas être autorisé à insérer et supprimer des éléments de manière arbitraire. Ça aurait dû être de la composition.
malheureusement, il est trop tard pour rectifier cette erreur de conception, car changer la hiérarchie des héritages briserait la compatibilité avec le code existant. avait Stack
utilisé la composition au lieu de l'héritage, il peut toujours être modifié pour utiliser une autre structure de données sans violer l'API .
je recommande vivement le livre de Josh Bloch Java efficace 2e édition
- Article 16: Favoriser la composition au cours de l'héritage
- rubrique 17: dessin ou modèle et document à transmettre ou à interdire
une bonne conception orientée objet ne consiste pas à étendre généreusement les classes existantes. Votre premier réflexe doit être de composer à la place.
Voir aussi:
Composition signifie HAS A
Héritage signifie IS A
Example
: voiture a un moteur et voiture est un Automobile
Dans la programmation c'est représentée comme:
class Engine {} // The Engine class.
class Automobile {} // Automobile class which is parent to Car class.
class Car extends Automobile { // Car is an Automobile, so Car class extends Automobile class.
private Engine engine; // Car has an Engine so, Car class has an instance of Engine class as its member.
}
comment l'héritage peut-il être dangereux ?
prenons un exemple
public class X{
public void do(){
}
}
Public Class Y extends X{
public void work(){
do();
}
}
1) comme il est clairement indiqué dans le code ci-dessus , la classe Y présente 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 une méthode de travail avec une signature inférieure
public int work(){
}
Le changement est fait dans la classe X, mais il rendra la classe Y Impossible à remplir. DONC, cette forme de dépendance peut aller jusqu'à de tout niveau et il peut varier dangereux. Chaque fois que superclass pourrait ne pas avoir la pleine visibilité pour coder à l'intérieur de toutes ses sous-classes et sous-classe peut être continuer à remarquer ce qui se passe dans suerclass tout le temps. Nous devons donc éviter ce couplage fort et inutile.
comment la composition résout-elle cette question?
permet de voir en révisant le même exemple
public class X{
public void do(){
}
}
Public Class Y{
X x=new X();
public void work(){
x.do();
}
}
ici nous créons la référence de la classe X dans la classe Y et invoquer la méthode de la classe X en créant une instance de la classe X. Maintenant, tout ce que le couplage fort est allé. La superclasse et la sous-classe sont très indépendantes l'une de l'autre maintenant. Les Classes peuvent librement faire des changements qui étaient dangereux dans la situation de l'héritage.
2) Deuxième très bon avantage de la composition en ce Qu'il fournit la méthode appelée flexibilité par exemple
class X implements R
{}
class Y implements R
{}
public class Test{
R r;
}
dans la classe D'essai en utilisant la Référence r je peux invoquer les méthodes de la classe X ainsi que Y classe. Cette flexibilité n'a jamais été là dans l'héritage
3) Un autre grand avantage: L'essai à L'Unité
public class X{
public void do(){
}
}
Public Class Y{
X x=new X();
public void work(){
x.do();
}
}
dans l'exemple ci-dessus si l'état de l'instance x n'est pas connu ,il peut facilement être mis en mémoire en utilisant certaines données d'essai et toutes les méthodes peuvent être facilement testées. Cela n'était pas du tout possible dans l'héritage car vous étiez fortement dépendant de superclass pour obtenir l'état de l'instance et exécuter n'importe quelle méthode.
4) Un Autre bien raison pour laquelle nous devrions éviter l'héritage est que Java ne supporte pas l'héritage multiple.
prenons un exemple pour comprendre :
Public class Transaction {
Banking b;
public static void main(String a[])
{
b=new Deposit();
if(b.deposit()){
b=new Credit();
c.credit();
}
}
}
bon à savoir:
-
la composition est facilement atteinte à l'exécution tandis que l'héritage fournit ses caractéristiques au moment de la compilation
-
la composition est également connu comme A-UNE relation et l'héritage est également connu sous le nom D'IS-une relation
ainsi en faire une habitude de toujours préférer la composition sur l'héritage pour diverses raisons ci-dessus.
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 de l'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 " is-a ". Si une voiture met en œuvre remplissable , la voiture " est-a remplissable , et peut être utilisé dans votre code partout où vous utiliseriez un remplissable .
La Compositionest fondamentalement différente de l'héritage. lorsque vous utilisez la composition, vous êtes (comme le notent les autres réponses) en train de faire un " has-a "relation entre deux objets, par opposition au" is-a " la relation que vous faites lorsque vous utilisez l'héritage .
donc, d'après les exemples de voiture dans les autres questions, si je voulais dire qu'une voiture " a-a "réservoir d'essence, j'utiliserais la composition, comme suit:
public class Car {
private GasTank myCarsGasTank;
}
ça devrait dissiper tout malentendu.
Héritage apporte EST-UN . Composition fait ressortir a-une relation .
Statergy pattern explique que la Composition devrait être utilisée dans les cas où il existe des familles d'algorithmes définissant un comportement particulier.
exemple classique d'une classe de canards qui met en œuvre un comportement de mouche.
public interface Flyable{
public void fly();
}
public class Duck {
Flyable fly;
public Duck(){
fly=new BackwardFlying();
}
}
ainsi nous pouvons avoir plusieurs classes qui implémentent volant par exemple:
public class BackwardFlying implements Flyable{
public void fly(){
Systemout.println("Flies backward ");
}
}
public class FastFlying implements Flyable{
public void fly(){
Systemout.println("Flies 100 miles/sec");
}
}
si cela avait été pour l'héritage nous aurions deux classes différentes d'oiseaux qui mettent en œuvre la fonction de mouche encore et encore.ainsi, l'héritage et la composition sont complètement différents.
la Composition est exactement comme elle sonne - vous créez un objet en le bouchant en plusieurs parties.
EDIT le reste de cette réponse est basé par erreur sur la prémisse suivante.
Ceci est accompli avec des Interfaces.
Par exemple, en utilisant l'exemple Car
ci-dessus,
Car implements iDrivable, iUsesFuel, iProtectsOccupants
Motorbike implements iDrivable, iUsesFuel, iShortcutThroughTraffic
House implements iProtectsOccupants
Generator implements iUsesFuel
ainsi avec quelques composants théoriques standard vous pouvez construire votre objet. C'est ensuite, votre travail de remplir comment un House
protège ses occupants, et comment un Car
protège ses occupants.
L'héritage est comme l'inverse. Vous commencez avec un objet complet (ou semi-complet) et vous remplacez ou Outrepassez les différents bits que vous voulez changer.
par exemple, MotorVehicle
peut venir avec une Fuelable
méthode et Drive
méthode. Vous pouvez laisser le carburant comme il est parce que c'est la même chose à remplir en haut d'une moto et d'une voiture, mais vous pouvez passer outre la méthode Drive
parce que la moto conduit très différemment à un Car
.
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és de passer outre. Avec la Composition, rien ne vous est donné. (mais vous pouvez implémenter les interfaces en appelant des méthodes dans d'autres classes si vous avez quelque chose autour de vous).
Composition est considéré comme plus flexible, parce que si vous avez une méthode comme iUsesFuel, vous pouvez avoir une méthode ailleurs (une autre classe, un autre projet) qui se soucie juste de traiter les objets qui peuvent être alimentés, indépendamment du fait que ce soit une voiture, bateau, cuisinière, barbecue, etc. Interfaces mandat que les classes qui implémentent cette interface effectivement les méthodes de cette interface est tout au sujet. Par exemple,
iFuelable Interface:
void AddSomeFuel()
void UseSomeFuel()
int percentageFull()
, alors vous pouvez avoir une méthode quelque part else
private void FillHerUp(iFuelable : objectToFill) {
Do while (objectToFill.percentageFull() <= 100) {
objectToFill.AddSomeFuel();
}
exemple étrange, mais il montre que cette méthode ne se soucie pas de ce qu'elle remplit, parce que l'objet met en œuvre iUsesFuel
, il peut être rempli. Fin de l'histoire.
si vous avez utilisé L'héritage à la place, vous auriez besoin de méthodes différentes FillHerUp
pour traiter avec MotorVehicles
et Barbecues
, à moins que vous n'ayez un objet de base" ObjectThatUsesFuel " assez bizarre dont hériter.
comme autre exemple, prenons une classe de voiture, ce serait une bonne utilisation de la composition, une voiture aurait "" un moteur, une transmission, pneus, sièges, etc. Il n'étendrait aucune de ces classes.
la Composition et L'héritage sont-ils les mêmes?
ils ne sont pas les mêmes.
Composition : elle permet à un groupe d'objets d'être traité de la même manière qu'une instance unique d'un objet. L'intention d'un composite est de "composer" des objets dans des structures d'arbre à représenter partie-entière des hiérarchies
héritage : une classe hérite des champs et des méthodes de toutes ses superclasses, qu'elles soient directes ou indirectes. Une sous-classe peut outrepasser les méthodes dont elle hérite, ou elle peut cacher des champs ou des méthodes dont elle hérite.
si je veux implémenter le pattern de composition, Comment puis-je le faire en Java?
Wikipedia article est assez bon pour mettre en œuvre motif composite en java.
Principaux Participants:
Composant :
- est l'abstraction pour tous les composants, y compris les composants
- déclare l'interface pour les objets dans la composition
Feuille :
- représente les objets en feuilles dans la composition
- met en œuvre tous les Composant méthodes
Composite :
- représente un composant composite (composant ayant des enfants)
- met en œuvre des méthodes de manipulation enfants
- met en œuvre toutes les méthodes composantes, généralement en les déléguant à ses enfants
exemple de Code pour comprendre Composite motif:
import java.util.List;
import java.util.ArrayList;
interface Part{
public double getPrice();
public String getName();
}
class Engine implements Part{
String name;
double price;
public Engine(String name,double price){
this.name = name;
this.price = price;
}
public double getPrice(){
return price;
}
public String getName(){
return name;
}
}
class Trunk implements Part{
String name;
double price;
public Trunk(String name,double price){
this.name = name;
this.price = price;
}
public double getPrice(){
return price;
}
public String getName(){
return name;
}
}
class Body implements Part{
String name;
double price;
public Body(String name,double price){
this.name = name;
this.price = price;
}
public double getPrice(){
return price;
}
public String getName(){
return name;
}
}
class Car implements Part{
List<Part> parts;
String name;
public Car(String name){
this.name = name;
parts = new ArrayList<Part>();
}
public void addPart(Part part){
parts.add(part);
}
public String getName(){
return name;
}
public String getPartNames(){
StringBuilder sb = new StringBuilder();
for ( Part part: parts){
sb.append(part.getName()).append(" ");
}
return sb.toString();
}
public double getPrice(){
double price = 0;
for ( Part part: parts){
price += part.getPrice();
}
return price;
}
}
public class CompositeDemo{
public static void main(String args[]){
Part engine = new Engine("DiselEngine",15000);
Part trunk = new Trunk("Trunk",10000);
Part body = new Body("Body",12000);
Car car = new Car("Innova");
car.addPart(engine);
car.addPart(trunk);
car.addPart(body);
double price = car.getPrice();
System.out.println("Car name:"+car.getName());
System.out.println("Car parts:"+car.getPartNames());
System.out.println("Car price:"+car.getPrice());
}
}
sortie:
Car name:Innova
Car parts:DiselEngine Trunk Body
Car price:37000.0
explication:
- partie est une feuille
- Car contient de nombreuses parties
- différentes parties du wagon ont été ajoutées au wagon
- le prix de La Voiture = somme ( Prix de chaque Partie )
se référer à la question ci-dessous pour les avantages et les inconvénients de la Composition et de L'héritage.
héritage entre deux classes, lorsqu'une classe s'étend une autre classe établit" est une relation ".
Composition sur l'autre contient une instance d'une autre classe dans votre classe établit " A Une relation". Composition en java est utile car il facilite techniquement multiples héritage.
par agrégation de mots simples, on entend une relation ..
la Composition est un cas particulier d'agrégation . Plus précisément, une agrégation restreinte est appelée composition. Lorsqu'un objet contient l'autre objet, si l'objet ne peut pas exister sans l'existence de l'objet conteneur, puis 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 élèves.
Pourquoi Utiliser L'Agrégation
Code Réutilisable
Quand Utiliser Agrégation
la réutilisation du Code est également mieux réalisée par agrégation lorsqu'il n'y a pas de Relation
héritage
L'héritage est une relation parent-enfant L'héritage est une relation
Inheritance en java est un mécanisme dans lequel un objet acquiert toutes les propriétés et les comportements de l'objet parent.
en utilisant l'héritage en Java 1 Code Réutilisable. 2 Ajouter des fonctionnalités supplémentaires dans la classe enfant ainsi que la méthode Overriding (donc le polymorphisme d'exécution peut être atteint).
est une Composition où quelque chose est composé de parties distinctes et il a une relation forte avec ces parties. Si la partie principale meurt les autres, ils ne peuvent pas avoir une vie qui leur est propre. Un exemple grossier est le corps humain. Enlevez le cœur et toutes les autres parties s'éteindront.
L'héritage, c'est quand on prend quelque chose qui existe déjà et qu'on l'utilise. Il n'y a pas de relation forte. Une personne peut hériter de la propriété de son père, mais il peut s'en passer.
Je ne connais pas Java donc je ne peux pas fournir un exemple mais je peux fournir une explication des concepts.
bien que L'héritage et la Composition fournissent la réutilisabilité 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 de la fonctionnalité. Une autre différence qui vient de ce fait est qu'en utilisant la Composition vous pouvez réutiliser le code pour même la classe finale qui n'est pas extensible mais L'héritage ne peut pas réutiliser le code dans de tels cas. Également à l'aide d' 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 d'une seule classe car en Java vous ne pouvez étendre qu'une seule classe, parce que L'héritage multiple n'est pas supporté en Java. Vous pouvez le faire en C++ cependant parce qu'il y a une classe qui peut étendre plus d'une classe. BTW, vous devriez toujours préférer la Composition à L'héritage en Java , ce n'est pas juste moi mais même Joshua Bloch a suggéré dans son livre
je pense que cet exemple explique clairement les différences entre héritage et 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 héritage , un changement de superclasse pourrait causer des problèmes dans la classe dérivée, qui héritent.
Là, vous pouvez également voir la différence dans représentation lorsque vous utilisez un UML pour l'héritage ou la composition.
Héritances Vs Composition.
Les héritages et la compositionsont utilisés pour la réutilisation et l'extension du comportement de classe.
héritages principalement utilisés dans un modèle de programmation d'algorithme de famille tel que IS-un type de relation signifie un type d'objet similaire. Exemple.
- Duster est un véhicule
- Safari est une voiture
ce sont appartient à la famille de Voitures.
Composition represents HAS-a relationship Type.Il montre la capacité d'un objet tel que Duster a cinq vitesses , Safari a quatre vitesses, etc. Chaque fois que nous avons besoin d'étendre la capacité d'une classe existante, puis utiliser la composition. exemple nous avons besoin d'ajouter un engrenage de plus dans L'objet Duster, puis nous devons créer un objet de plus et le composer à l'objet duster.
nous ne devrions pas faire les changements de base la classe jusqu'à ce que toutes les classes dérivées besoin de ces fonctionnalités.Pour ce scénario, nous devrions utiliser la Composition.Comme
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 si les classes C et d n'ont pas besoin de ces fonctionnalités.Pour ce scénario, nous avons besoin de créer un classe pour ceux de la fonctionnalité et de composer pour la classe(ici est la classe B).
ci-dessous est l'exemple:
// This is a base class
public abstract class Car
{
//Define prototype
public abstract void color();
public void Gear() {
Console.WriteLine("Car has a four Gear");
}
}
// Here is the use of inheritence
// This Desire class have four gears.
// But we need to add one more gear that is Neutral gear.
public class Desire : Car
{
Neutral obj = null;
public Desire()
{
// Here we are incorporating neutral gear(It is the use of composition).
// Now this class would have five gear.
obj = new Neutral();
obj.NeutralGear();
}
public override void color()
{
Console.WriteLine("This is a white color car");
}
}
// This Safari class have four gears and it is not required the neutral
// gear and hence we don't need to compose here.
public class Safari :Car{
public Safari()
{ }
public override void color()
{
Console.WriteLine("This is a red color car");
}
}
// This class represents the neutral gear and it would be used as a composition.
public class Neutral {
public void NeutralGear() {
Console.WriteLine("This is a Neutral Gear");
}
}
Composition désigne la création d'un objet d'une classe qui a une relation avec cette classe particulière. Supposons que L'étudiant ait une relation avec les comptes;
"151900920 Un" Héritage est, c'est la classe précédente avec la fonction étendue. Cela signifie que cette nouvelle classe est L'ancienne classe avec certaines fonctionnalités étendues. Supposons que L'étudiant est L'étudiant, mais que tous les étudiants sont humains. Il y a donc une relation avec l'étudiant et l'humain. C'est l'Héritage.non, les deux sont différents . La Composition suit la relation" a-A "et l'héritage suit la relation" est-a". Le meilleur exemple pour la composition était le schéma stratégique .
héritage signifie réutiliser la fonctionnalité complète d'une classe, ici ma classe doit utiliser toutes les méthodes de la super classe et ma classe sera titely couplé avec la super classe et le code sera dupliqué dans les deux classes en cas d'héritage.
mais nous pouvons surmonter de tous ces problèmes quand nous utilisons la composition pour parler avec une autre classe . la composition est déclarer un attribut d'une autre classe dans ma classe à laquelle nous voulons parler. et ce la fonctionnalité que nous voulons de cette classe nous pouvons obtenir en utilisant cet attribut.