Différence entre Héritage et Composition


La composition et l'héritage sont-ils identiques? Si je veux implémenter le modèle de composition, comment puis-je le faire en Java?

Author: Péter Török, 2010-03-08

17 answers

Ils sont absolument différents. L'héritage est un "est-un" relation. La composition est un "a-a".

Vous faites de 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. Ceci est maintenant considéré comme une erreur. Une pile "n'est PAS un" vecteur; vous ne devriez pas être autorisé à insérer et supprimer des éléments arbitrairement. Ça aurait dû être de la composition à la place.

Malheureusement, il est trop tard pour rectifier cette erreur de conception, car changer la hiérarchie d'héritage maintenant 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 Effective Java 2nd Edition

  • Article 16: Favoriser la composition sur héritage
  • Point 17: Conception et document pour l'héritage ou bien l'interdire

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 aussi:

 243
Author: polygenelubricants, 2010-03-08 06:22:45

Composition signifie HAS A
L'héritage signifie IS A

Example: Voiture est un Moteur et la Voiture est un Automobile

En programmation, cela est représenté par:

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.
}
 156
Author: codaddict, 2017-07-30 22:13:28

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 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 casser considérablement. Supposons que Dans la future classe X implémente un travail de méthode avec la signature ci-dessous

public int work(){
}

Le changement est fait dans la classe X mais il rendra la classe Y non compilable. DONC, cette forme de dépendance peut aller jusqu'à n'importe quel niveau et il peut varier dangereux. Chaque fois superclasse pourrait 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 suerclass tout le temps. Nous devons donc éviter ce couplage fort et inutile.

Comment la composition résout - elle ce problème?

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 invoquons la méthode de la classe X en créant une instance de la classe X. Maintenant, tout ce couplage fort a disparu. Superclasse et sous-classe sont très indépendants les uns des autres maintenant. Les classes peuvent librement faire des changements qui étaient dangereux dans la situation d'héritage.

2) Deuxième très bon avantage de la composition en ce qu'Elle fournit une flexibilité d'appel de méthode Par exemple

class X implements R
{}
class Y implements R
{}

public class Test{    
    R r;    
}

Dans la classe de 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

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 est pas connu, il peut facilement être moqué en utilisant des données de test et toutes les méthodes peuvent être facilement testées. Cela n'était pas possible du tout dans l'héritage Car vous étiez fortement dépendant de la superclasse pour obtenir l'état de l'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 :

Public class Transaction {
    Banking b;
    public static void main(String a[])    
    {    
        b=new Deposit();    
        if(b.deposit()){    
            b=new Credit();
            c.credit();    
        }
    }
}

Bon à savoir :

  1. La composition est facilement atteint à l'exécution alors que l'héritage fournit ses fonctionnalités au moment de la compilation

  2. La Composition est également connu comme A-UNE relation et l'héritage est également connu comme UN rapport

Prenez donc l'habitude de toujours préférer la composition à l'héritage pour diverses raisons ci-dessus.

 20
Author: Manoj Kumar Saini, 2013-07-29 05:48:09

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 n'héritez pas seulement de toutes les constantes, vous validez votre objet pour qu'il soit du type spécifié par l'interface; c'est toujours une relation "is-a". Si une voiture implémente Comment, la voiture "est un" Comment, et peut être utilisé dans votre code chaque fois que vous utilisez un Comment.

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-a" gaz réservoir, je voudrais utiliser la composition, comme suit:

public class Car {

private GasTank myCarsGasTank;

}

Espérons que cela dissipe tout malentendu.

 16
Author: Kris, 2016-09-26 16:00:45

L'Héritage apporte EST UN relation. La composition fait ressortir A une relation . Statergy pattern 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 d'une classe duck qui implémente 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 le vol 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 c'était pour l'héritage, nous aurions deux différents classes 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.

 14
Author: frictionlesspulley, 2010-06-29 05:38:20

La composition est comme elle semble - vous créez un objet en branchant des parties.

EDIT 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'exemple Car ci-dessus,

Car implements iDrivable, iUsesFuel, iProtectsOccupants
Motorbike implements iDrivable, iUsesFuel, iShortcutThroughTraffic
House implements iProtectsOccupants
Generator implements iUsesFuel

Donc, avec quelques composants théoriques standard, vous pouvez construire votre objet. C'est votre travail pour remplir un House protège ses occupants, et comment un Car protège ses occupant.

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 un Fuelable méthode et Drive méthode. Vous pouvez laisser la méthode de carburant telle qu'elle est parce que c'est la même chose pour remplir une moto et une voiture, mais vous pouvez remplacer la méthode Drive parce que la moto conduit très différemment d'un Car.

Avec héritage, certains les classes sont déjà complètement implémentées et d'autres ont des méthodes que vous êtes obligé de remplacer. 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 qui traîne).

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 ne s'inquiète que de traiter des objets pouvant être alimentés, qu'il s'agisse d'une voiture, bateau, cuisinière, barbecue, etc. Les interfaces exigent que les classes qui disent implémenter cette interface aient réellement les méthodes dont cette interface est l'objet. Par exemple,

iFuelable Interface:
   void AddSomeFuel()
   void UseSomeFuel()
   int  percentageFull()

Alors vous pouvez avoir une méthode ailleurs

private void FillHerUp(iFuelable : objectToFill) {

   Do while (objectToFill.percentageFull() <= 100)  {

        objectToFill.AddSomeFuel();
   }

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 avez utilisé l'héritage à la place, vous aurait besoin de différentes méthodes FillHerUp pour traiter MotorVehicles et Barbecues, à moins que vous n'ayez un objet de base "ObjectThatUsesFuel" plutôt étrange dont hériter.

 7
Author: Michael Rodrigues, 2013-12-19 22:27:38

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.

 4
Author: BlackICE, 2010-03-08 05:58:50

La composition et l'héritage sont-ils identiques?

Ils ne sont pas les mêmes.

Composition : Elle permet à un groupe d'objets doivent être traités de la même façon 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 partie-ensemble

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 remplacer les méthodes qu'il hérite, ou il peut masquer des champs ou méthodes qu'il hérite.

Si je veux implémenter le modèle de composition, comment puis-je le faire en Java?

Wikipedia l'article est assez bon pour implémenter un motif composite en java.

entrez la description de l'image ici

Les Principaux Participants:

Composant:

  1. Est l'abstraction pour tous les composants, y compris composite les
  2. Déclare l'interface pour les objets dans la composition

Feuille:

  1. Représente les objets feuilles dans la composition
  2. Implémente toutes les méthodes Component

Composite:

  1. Représente un composant composite (composant ayant des enfants)
  2. Implémente des méthodes pour manipuler les enfants
  3. Implémente toutes les méthodes de composant, généralement en déléguant à ses enfants

Exemple de code pour comprendreMotif composite :

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:

  1. Partie est une feuille
  2. Voiture contient de nombreuses Pièces de
  3. Différente Pièces de la voiture ont été ajoutés à la Voiture
  4. Le prix de Voiture = somme de ( Prix de chaque la Partie )

Se référer à 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?

 4
Author: Ravindra babu, 2017-05-23 11:33:26

Héritage entre deux classes, où une classe étend une autre classe établit " EST une relation".

Composition sur l'autre extrémité contient une instance d'une autre classe dans votre classe établit "A Un" relation. La composition en java est utile car elle facilite techniquement l'héritage multiple.

 3
Author: John Wilson, 2016-09-24 18:12:39

Dans Les Moyens Simples D'Agrégation De Mots A Une Relation ..

La composition est un cas particulier d'agrégation . D'une manière plus spécifique, 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 étudiants. Un étudiant ne peut exister sans classe. Il existe une composition entre la classe et étudiant.

Pourquoi Utiliser L'Agrégation

Réutilisabilité 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

L'Héritage

L'héritage est une Relation Parent-enfant L'héritage Signifie Une relation

L'héritage en java est un mécanisme dans lequel un objet acquiert toutes les propriétés et comportements de l'objet parent.

En utilisant l'héritage en Java 1 Réutilisabilité du code. 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).

 3
Author: Keshav Gera, 2017-06-12 12:22:52

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 meurt, les autres aussi, ils ne peuvent pas avoir une vie propre. Un exemple approximatif est le corps humain. Sortez le cœur et toutes les autres parties meurent.

L'héritage est l'endroit où vous prenez juste quelque chose qui existe déjà et l'utilisez. Il n'y a pas de relation forte. Une personne pourrait hériter de la succession de son père, mais elle peut s'en passer.

Je ne sais pas Java donc je ne peux pas fournir un exemple mais je peux fournir une explication des concepts.

 2
Author: Robert Rocha, 2015-01-08 18:11:17

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 de code ou de fonctionnalité. Une autre différence qui vient de ce fait est qu'en utilisant la composition, vous pouvez réutiliser le 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. Aussi en utilisant la composition vous pouvez réutiliser le code de nombreuses classes car elles sont déclarées comme une variable membre, mais avec l'héritage, vous pouvez réutiliser le code sous forme d'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 plus d'une classe. BTW, Vous devriez toujours préférer la composition à l'héritage en Java , ce n'est pas seulement moi mais même Joshua Bloch{[4] } a suggéré dans son livre

 2
Author: Nitin Pawar, 2015-06-03 10:55:59

Je pense que cet exemple explique clairement les différences entre les 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 peut causer 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 composition.

Http://www.javaworld.com/article/2076814/core-java/inheritance-versus-composition--which-one-should-you-choose-.html

 1
Author: aunte, 2016-11-07 16:51:38

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 utilisent principalement dans un modèle de programmation d'algorithme familial tel que IS-Un type de relation signifie un type d'objet similaire. Exemple.

  1. Duster est une voiture
  2. Safari est une Voiture

Ceux-ci appartiennent à la famille de voitures.

La composition représente la relation HAS-A Type.It montre la capacité d'un objet tels que Duster a cinq vitesses, Safari a quatre vitesses, etc. Chaque fois que nous avons besoin d'étendre la capacité d'une classe existante, utilisez la composition.Exemple nous devons ajouter un engrenage de plus dans l'objet Duster, puis nous devons créer un objet gear de plus et le composer dans l'objet duster.

Nous ne devrions pas apporter les modifications dans la classe de base jusqu'à/sauf si toutes les classes dérivées avaient besoin de ces fonctionnalités.Pour ce scénario, nous devrions utiliser la composition.Tels que

Classe A Dérivée par classe B

Classe A Dérivée par classe C

Classe A Dérivée par 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 n'ont pas besoin de 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).

Ci-Dessous 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");
                       }
                   }
 1
Author: Sheo Dayal Singh, 2017-08-19 11:56:19

Composition signifie créer un objet dans une classe qui a une relation avec cette classe particulière. Supposons que l'étudiant ait une relation avec les comptes;

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 une fonctionnalité étendue. 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.

 0
Author: HM Nayem, 2017-06-09 22:31:08

Non , les deux sont différents . Composition suivre" A-A "relation et héritage suivre" EST-A " relation . Le meilleur exemple pour la composition était le modèle stratégique .

 0
Author: Ranga Reddy, 2017-12-24 17:34:46

L'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 couplée à 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 . la 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.

 0
Author: Vikas Kapadiya, 2018-02-07 09:21:10