Quelle est la principale différence entre l'héritage et le polymorphisme?

172

On m'a posé cette question dans un examen de fin de module à livre ouvert aujourd'hui et je me suis retrouvé perdu. Je lisais Head first Javaet les deux définitions semblaient être exactement les mêmes. Je me demandais simplement quelle était la différence PRINCIPALE pour ma propre tranquillité d'esprit. Je sais qu'il y a un certain nombre de questions similaires à cela, mais je n'en ai vu aucune qui apporte une réponse définitive.

Darren Burgess
la source

Réponses:

289

L'héritage se produit lorsqu'une «classe» dérive d'une «classe» existante. Donc, si vous avez une Personclasse, alors vous avez une Studentclasse qui s'étend Person, Student hérite de tout ce qui Persona. Il y a quelques détails sur les modificateurs d'accès que vous mettez sur les champs / méthodes dans Person, mais c'est l'idée de base. Par exemple, si vous avez un champ privé activé Person, Studentne le verra pas car ses champs privé et privé ne sont pas visibles pour les sous-classes.

Le polymorphisme traite de la manière dont le programme décide des méthodes qu'il doit utiliser, en fonction du type d'objet dont il dispose. Si vous avez un Person, qui a une readméthode, et vous avez un Studentqui s'étend Person, qui a sa propre implémentation de read, quelle méthode est appelée est déterminée pour vous par le runtime, selon que vous avez un Personou un Student. Cela devient un peu délicat, mais si vous faites quelque chose comme

Person p = new Student();
p.read();

la méthode read sur Student est appelée. C'est le polymorphisme en action. Vous pouvez faire cette affectation car a Student est a Person , mais le runtime est suffisamment intelligent pour savoir que le type réel de pest Student .

Notez que les détails diffèrent selon les langues. Vous pouvez faire de l'héritage en javascript par exemple, mais c'est complètement différent de la façon dont cela fonctionne en Java.

hvgotcodes
la source
9
@ hvgtcodes donc en un mot, la relation superclasse-sous-classe est l'héritage et le concept d'implémentation de la même méthode d'une manière différente entre la classe parente et ses sous-classes, et les appelle en fonction de la situation sont Polymorphisme. Ai-je raison?
Muhammad Raihan Muhaimin
1
@hvgotcodes mais disons que si Personla readméthode utilise le modificateur d'accès public, les Studentobjets ne pourront-ils pas y accéder? et alors Student s = new Student();ce ne sera pas plus facile? Je ne profite toujours pas vraiment des avantages du polymporphisme.
Scorpiorian83
1
@hvgotcodes Student s = new Student () fonctionnerait. Mais disons qu'après avoir écrit une grande partie du code en utilisant cette idée, et plus tard, vous vous rendez compte que vous avez fait une erreur. La personne n'est en fait pas un élève, c'est un enseignant. Vous pouvez donc simplement passer de Person p = new Student () à Person p = new Teacher (), alors cela vous simplifiera la vie.
munmunbb
Ma question ici serait de savoir pourquoi voudriez-vous utiliser Person p = new Student(); place de Student p = new Student();?
PerfectContrast
@PerfectContrast Je pense que c'est utile lorsque vous voulez avoir un étudiant, un chauffeur, un enseignant, etc. en tant que personne et que vous les regroupez sous une liste ou quelque chose comme ça. Ainsi, lorsque vous appelez «lecture» pour tous, chacun appelle sa propre méthode «lecture».
savante le
205

L'héritage fait référence à l' utilisation de la structure et du comportement d'une super-classe dans une sous-classe.

Le polymorphisme fait référence à la modification du comportement d'une super-classe dans la sous-classe.

Ted Hopp
la source
5
Cette réponse implique-t-elle que le polymorphisme nécessite un héritage?
jaco0646
6
@ jaco0646 - Dans le contexte de Java, je pense que oui. (Dans d'autres langages, peut-être pas tellement.) Notez que «super classe» et «sous-classe» sont utilisés ici de manière lâche. Le polymorphisme peut également signifier l'héritage d'un comportement spécifié (mais non implémenté) dans une interface.
Ted Hopp
1
@AlirezaRahmani - Je ne comprends pas votre commentaire. Voulez-vous dire que l'héritage n'implique pas l'héritage à la fois des propriétés et du comportement? Ce serait contraire à la façon dont Java (et la plupart des langages orientés objet basés sur des classes) définissent l'héritage. D'après la spécification du langage Java, §8.4.8 : "Une classe C hérite de sa superclasse directe toutes les méthodes concrètes m(à la fois staticet instance) de la superclasse pour lesquelles ..." (suivi de détails sur l'héritage). Cela ressemble à une «réutilisation du code» pour moi.
Ted Hopp
@TedHopp Inheritance est avant tout un outil polymorphe, mais certaines personnes, à leurs risques et périls ultérieurs, tentent de l'utiliser comme moyen de réutiliser / partager du code. La justification étant "bien si j'hérite alors j'obtiens toutes les méthodes gratuitement", mais en ignorant le fait que ces deux classes n'ont potentiellement aucune relation polymorphe.
Alireza Rahmani Khalili
1
@AlirezaRahmani - En Java (ce que OP a spécifiquement demandé, selon les balises), l'héritage de classe implique très certainement l'héritage du comportement. Cela fait partie de la définition de la langue. Le fait que cela puisse être mal utilisé comme vous le décrivez est l'une des faiblesses de Java. (Une faiblesse connexe impliquait de déclarer des classes pour implémenter des interfaces simplement pour importer les constantes définies dans l'interface. Finalement, les concepteurs Java ont introduit import staticpour éliminer cette mauvaise utilisation des interfaces.) Pour le polymorphisme pur en Java, l'outil à utiliser est les interfaces, pas l'héritage de classe.
Ted Hopp
63

Polymorphisme : capacité à traiter des objets de différents types de manière similaire. Exemple: la girafe et le crocodile sont tous les deux des animaux, et les animaux le peuvent Move. Si vous avez une instance d'unAnimal vous pouvez appeler Movesans savoir ni vous soucier de quel type d'animal il s'agit.

Héritage : c'est une façon de réaliser à la fois le polymorphisme et la réutilisation du code.

Autres formes de polymorphisme : il existe d'autres moyens de réaliser le polymorphisme, comme les interfaces, qui ne fournissent que du polymorphisme mais pas de réutilisation du code (parfois le code est assez différent, commeMove pour un Snake serait assez différent de celui Moved'un Chien, auquel cas une Interface serait le meilleur choix polymorphe dans ce cas.

Dans d'autres langages dynamiques, le polymorphisme peut être réalisé avec Duck Typing, c'est-à-dire que les classes n'ont même pas besoin de partager la même classe ou interface de base, elles ont juste besoin d'une méthode avec le même nom. Ou encore plus dynamique comme Javascript, vous n'avez même pas besoin de classes du tout, juste un objet avec le même nom de méthode peut être utilisé de manière polymorphe.

Davy8
la source
17

La principale différence est que le polymorphisme est un résultat spécifique de l'héritage. Le polymorphisme est l'endroit où la méthode à invoquer est déterminée à l'exécution en fonction du type de l'objet. Il s'agit d'une situation qui se produit lorsqu'une classe hérite d'une autre et remplace une méthode particulière. Cependant, dans une arborescence d'héritage normale, vous ne devez remplacer aucune méthode et donc tous les appels de méthode ne doivent pas nécessairement être polymorphes. Cela a-t-il du sens? C'est un problème similaire à tous les véhicules Ford sont des automobiles, mais toutes les automobiles ne sont pas des Ford (mais pas tout à fait ....).

De plus, le polymorphisme traite de l'invocation de méthode tandis que l'héritage décrit également les membres de données, etc.

Chris Thompson
la source
12

En Java, les deux sont étroitement liés. Cela est dû au fait que Java utilise une technique d'invocation de méthode appelée «répartition dynamique». Si j'ai

public class A {
  public void draw() { ... }
  public void spin() { ... }
}

public class B extends A {
  public void draw() { ... }
  public void bad() { ... }
}

...

A testObject = new B();

testObject.draw(); // calls B's draw, polymorphic
testObject.spin(); // calls A's spin, inherited by B
testObject.bad(); // compiler error, you are manipulating this as an A

Ensuite, nous voyons que B hérite spinde A. Cependant, lorsque nous essayons de manipuler l'objet comme s'il s'agissait d'un type A, nous obtenons toujours le comportement de B pour draw. Le drawcomportement est polymorphe.

Dans certaines langues, le polymorphisme et l'héritage ne sont pas aussi étroitement liés. En C ++, par exemple, les fonctions non déclarées virtuelles sont héritées, mais ne seront pas distribuées dynamiquement, donc vous n'obtiendrez pas ce comportement polymorphe même lorsque vous utilisez l'héritage.

En javascript, chaque appel de fonction est distribué dynamiquement et vous avez un typage faible. Cela signifie que vous pourriez avoir un tas d'objets non liés, chacun avec le leur draw, avoir une fonction itérer sur eux et appeler la fonction, et chacun se comporterait très bien. Vous auriez votre propre tirage polymorphe sans avoir besoin d'héritage.

ccoakley
la source
12

Polymorphisme: Supposons que vous travaillez pour une entreprise qui vend des stylos. Vous créez donc une très belle classe appelée "Pen" qui gère tout ce que vous devez savoir sur un stylo. Vous écrivez toutes sortes de classes pour la facturation, l'expédition, la création de factures, le tout en utilisant la classe Pen. Un patron de jour arrive et dit: "Excellente nouvelle! La société se développe et nous vendons des livres et des CD maintenant!" Ce n'est pas une bonne nouvelle car maintenant vous devez changer chaque classe qui utilise Pen pour utiliser également Book & CD. Mais que se passerait-il si vous aviez initialement créé une interface appelée "SellableProduct" et que Pen implémentait cette interface. Ensuite, vous pourriez avoir écrit toutes vos classes d'expédition, de facturation, etc. pour utiliser cette interface au lieu de Pen. Il ne vous reste plus qu'à créer une nouvelle classe appelée Book & CompactDisc qui implémente l'interface SellableProduct. En raison du polymorphisme, toutes les autres classes pourraient continuer à fonctionner sans changement! Faire du sens?

Donc, cela signifie utiliser l'héritage qui est l'un des moyens d'atteindre le polymorphisme.

Le polymorphisme peut être possible dans une classe / interface mais l'héritage toujours entre 2 OU plusieurs classes / interfaces. L'héritage est toujours conforme à la relation «est-une» alors qu'elle ne l'est pas toujours avec le polymorphisme (qui peut conformer à la fois la relation «est-un» / «a-une».

AmitK
la source
6

L'héritage est plus une chose statique (une classe en étend une autre) tandis que le polymorphisme est une chose dynamique / d'exécution (un objet se comporte selon son type dynamique / d'exécution et non selon son type statique / déclaration).

Par exemple

// This assignment is possible because B extends A
A a = new B();
// polymorphic call/ access
a.foo();

-> Bien que le type statique / déclaration de a soit A, le type dynamique / d'exécution réel est B et donc a.foo () exécutera foo comme défini dans B pas dans A.

Puce
la source
3

Le polymorphisme est une approche permettant d'exprimer un comportement commun entre des types d'objets qui ont des traits similaires. Cela permet également de créer des variations de ces traits par substitution. L'héritage est un moyen d'atteindre le polymorphisme à travers une hiérarchie d'objets où les objets expriment des relations et des comportements abstraits. Ce n'est cependant pas le seul moyen d'atteindre le polymorphisme. Le prototype est une autre façon d'exprimer le polymorphisme qui est différent de l'héritage. JavaScript est un exemple de langage qui utilise un prototype. J'imagine qu'il existe également d'autres moyens.

laz
la source
3

L'héritage est un concept lié à la réutilisation du code. Par exemple, si j'ai une classe parent dire Animalet qu'elle contient certains attributs et méthodes (pour cet exemple, dites makeNoise()et sleep()) et que je crée deux classes enfants appelées Doget Cat. Puisque les chiens et les chats s'endorment de la même manière (je suppose), il n'est pas nécessaire d'ajouter plus de fonctionnalités à la sleep()méthode dans les sous Dog- Catclasses et fournies par la classe parente Animal. Cependant, un Dogaboiement et un Catmiaulement alors queAnimalla classe peut avoir une méthode pour faire du bruit, un chien et un chat font des bruits différents les uns par rapport aux autres et aux autres animaux. Ainsi, il est nécessaire de redéfinir ce comportement pour leurs types spécifiques. Ainsi la définition du polymorphisme. J'espère que cela t'aides.

vengeur12
la source
3

La documentation Oracle a cité la différence avec précision.

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 dont elle hérite ou masquer les champs ou les méthodes dont elle hérite . (Notez que masquer des champs est généralement une mauvaise pratique de programmation.)

polymorphisme: le polymorphisme fait référence à un principe de biologie dans lequel un organisme ou une espèce peut avoir de nombreuses formes ou stades différents. Ce principe peut également être appliqué à la programmation orientée objet et aux langages comme le langage Java. Les sous-classes d'une classe peuvent définir leurs propres comportements uniques tout en partageant certaines des mêmes fonctionnalités de la classe parent.

le polymorphisme ne s'applique pas aux champs.

Article similaire:

Polymorphisme vs écrasement vs surcharge

Ravindra babu
la source
1

Le polymorphisme est un effet d' héritage . Cela ne peut se produire que dans des classes qui s'étendent les unes les autres. Il vous permet d'appeler des méthodes d'une classe sans connaître le type exact de la classe. En outre, le polymorphisme se produit au moment de l'exécution .

Par exemple, exemple de polymorphisme Java:

entrez la description de l'image ici

L'héritage permet aux classes dérivées de partager les interfaces et le code de leurs classes de base. Cela se produit au moment de la compilation .

Par exemple, toutes les classes de la plateforme Java sont des descendants d'objet (image fournie par Oracle):

entrez la description de l'image ici

Pour en savoir plus sur l'héritage Java et le polymorphisme Java

Johnny
la source
0

L'héritage se produit lorsque la classe A hérite de toutes les méthodes / champs non statiques protégés / publics de tous ses parents jusqu'à Object.

Cosmin Cosmin
la source
0

Si vous utilisez JAVA, c'est aussi simple que ceci:

Le polymorphisme utilise des méthodes héritées mais les «écrasant» pour faire quelque chose de différent (ou la même chose si vous appelez super donc ne serait pas techniquement polymorphe).

Corrige moi si je me trompe.

Oliver Dixon
la source
0

Le principal objectif du polymorphisme : créer une variable de référence à la super classe et tenir l' objet de la sous - classe => un objet peut effectuer plusieurs comportements .

En héritage , la sous - classe hérite des propriétés de la super classe .

satya
la source
0

l'héritage est une sorte de polymorphisme. En fait, l'héritage est le polymorphisme dynamique. Ainsi, lorsque vous supprimez l'héritage, vous ne pouvez plus remplacer.

Alireza Rahmani Khalili
la source
0

Avec l' héritage, l'implémentation est définie dans la superclasse - le comportement est donc hérité.

class Animal
{
  double location;
  void move(double newLocation)
  {
    location = newLocation;
  }
}

class Dog extends Animal;

Avec Polymorphism, l'implémentation est définie dans la sous-classe - donc seule l' interface est héritée.

interface Animal
{
  void move(double newLocation);
}

class Dog implements Animal
{
  double location;
  void move(double newLocation)
  {
    location = newLocation;
  }
}
Mherzl
la source
0

Le polymorphisme est obtenu par héritage dans Java.

├── Animal
└── (instances)
    ├── Cat
    ├── Hamster
    ├── Lion
    └── Moose

├── interface-for-diet
   ├── Carnivore
   └── Herbivore
├── interface-for-habitat
   ├── Pet
   └── Wild

public class Animal {
    void breath() {
    };
}

public interface Carnivore {
    void loveMeat();
}

public interface Herbivore {
    void loveGreens();
}

public interface Pet {
    void liveInside();
}

public interface Wild {
    void liveOutside();
}

public class Hamster extends Animal implements Herbivore, Pet {

    @Override
    public void liveInside() {
        System.out.println("I live in a cage and my neighbor is a Gerbil");
    }

    @Override
    public void loveGreens() {
        System.out.println("I eat Carrots, Grapes, Tomatoes, and More");
    }
}

public class Cat extends Animal implements Carnivore, Pet {
    @Override
    public void liveInside() {
        System.out.println("I live in a cage and my neighbr is a Gerbil");
    }

    @Override
    public void loveMeat() {
        System.out.println("I eat Tuna, Chicken, and More");
    }
}

public class Moose extends Animal implements Herbivore, Wild {

    @Override
    public void liveOutside() {
        System.out.println("I live in the forest");
    }

    @Override
    public void loveGreens() {
        System.out.println("I eat grass");
    }
}

public class Lion extends Animal implements Carnivore, Wild {

    @Override
    public void liveOutside() {
        System.out.println("I live in the forest");
    }

    @Override
    public void loveMeat() {
        System.out.println("I eat Moose");
    }
}

Hamsterclasse hérite la structure de Animal, Herbivoreet Petd'exposer behaviorisme polymorphes d'un animal domestique.

Catclasse hérite de la structure de Animal, Carnivoreet Petprésente également behaviorisme polymorphes d'un animal domestique.

nabster
la source