web-dev-qa-db-fra.com

Essayez de décrire le polymorphisme aussi facilement que possible

Comment décrire le polymorphisme de manière simple à comprendre?

Nous pouvons trouver beaucoup d'informations sur le sujet sur Internet et dans des livres, comme dans Polymorphisme de type. Mais essayons de le rendre aussi simple que possible.

58
Moran Helman

C'est de ma réponse d'une question similaire. Voici un exemple de polymorphisme en pseudo-C #/Java:

class Animal
{
    abstract string MakeNoise ();
}

class Cat : Animal {
    string MakeNoise () {
        return "Meow";
    }
}

class Dog : Animal {
    string MakeNoise () {
        return "Bark";
    }
}

Main () {
   Animal animal = Zoo.GetAnimal ();
   Console.WriteLine (animal.MakeNoise ());
}

La méthode Main () ne connaît pas le type de l'animal et dépend du comportement d'une implémentation particulière de la méthode MakeNoise ().

31
Mark A. Nicolosi

Deux objets répondent au même message avec des comportements différents; l'expéditeur n'a pas à s'en soucier.

67
Steven A. Lowe

Chaque boîte avec un simple couvercle pop s'ouvre de la même manière.
En tant qu'être humain, vous savez que vous pouvez ouvrir () tout ce que vous pouvez trouver.

Lorsqu'elles sont ouvertes, toutes les boîtes ne se comportent pas de la même manière.
Certains contiennent des noix, certains contiennent de faux serpents qui sortent.
Le résultat dépend du TYPE de canette, si la canette était un "CanOfNuts" ou un "CanOfSnakes", mais cela n'a aucune incidence sur la façon dont vous l'ouvrez. Vous savez simplement que vous pouvez ouvrir n'importe quelle boîte, et vous obtiendrez une sorte de résultat qui sera décidé en fonction du type de boîte que vous avez ouvert.

pUnlabledCan-> Open (); // pourrait donner des noix, pourrait donner des serpents. Nous ne savons pas jusqu'à ce que nous l'appelions

Open () a un type de retour générique de "Contenu" (ou nous pourrions décider de ne pas choisir de type de retour), de sorte que open a toujours la même signature de fonction.

Vous, l'humain, êtes l'utilisateur/l'appelant.
Open () est la fonction virtuelle/polymorphe.
"Can" est la classe de base abstraite.
CanOfNuts et CanOfSnakes sont les enfants polymorphes de la classe "Can".
Chaque boîte peut être ouverte, mais ce qu'elle fait spécifiquement et quel type spécifique de contenu il retourne sont définis par quelle sorte de bidon c'est.
Tout ce que vous savez quand vous voyez pUnlabledCan, c'est que vous pouvez l'ouvrir (), et il retournera le contenu. Tous les autres comportements (tels que des serpents à éclater dans votre visage) sont décidés par le Can spécifique.

32
David Frenkel

La description la plus simple du polymorphisme est que c'est un moyen de réduire les instructions if/switch.

Il a également l'avantage de vous permettre d'étendre vos instructions if/switch (ou celles d'autres personnes) sans modifier les classes existantes.

Par exemple, considérez la classe Stream dans .NET. Sans polymorphisme, ce serait une seule classe massive où chaque méthode implémente une instruction switch quelque chose comme:

public class Stream
{
    public int Read(byte[] buffer, int offset, int count)
    {
        if (this.mode == "file")
        {
            // behave like a file stream
        }
        else if (this.mode == "network")
        {
            // behave like a network stream
        }
        else // etc.
    }
}

Au lieu de cela, nous permettons au runtime de faire la commutation pour nous de manière plus efficace, en choisissant automatiquement l'implémentation en fonction du type concret (FileStream, NetworkStream), par exemple.

public class FileStream : Stream
{
    public override int Read(byte[] buffer, int offset, int count)
    {
        // behave like a file stream
    }
}

public class NetworkStream : Stream
{
    public override int Read(byte[] buffer, int offset, int count)
    {
        // behave like a network stream
    }
}
20
Greg Beech

Poly: beaucoup
Morphisme: formes/formes

10
Cyber Oliveira

Les pommes et les oranges sont toutes deux des fruits. Les fruits peuvent être mangés. Par conséquent, les pommes et les oranges peuvent être consommées.

Le kicker? Vous les mangez différemment! Vous épluchez les oranges, mais pas les pommes.

Donc, la mise en œuvre diffère, mais le résultat final est le même, vous mangez le fruit.

L'acteur contre le personnage (ou le rôle)

6
Ovidiu Pacurar

S'il marche comme un canard et qu'il pleure comme un canard, vous pouvez le traiter comme un canard partout où vous avez besoin d'un canard.

4
kurosch

C'est un meilleur article en fait

Le polymorphisme permet aux objets de "se ressembler", mais de se comporter de différentes manières. L'exemple habituel est de prendre une classe de base animale avec une méthode Speak (), une sous-classe de chien émettrait un écorce tandis qu'une sous-classe de porc émettrait un oink.

La réponse courte de 5 secondes que la plupart des gens utilisent pour que les autres développeurs puissent se renseigner Le polymorphisme est surchargé et primordial

3
JamesSugrue

Même syntaxe, sémantique différente.

2
Mark Reid

Manière la plus simple de le décrire: un verbe qui peut s'appliquer à plus d'un type d'objet.

Tout le reste, comme l'a dit Hillel, n'est qu'un commentaire.

1
pookleblinky

Le polymorphisme divise le monde en boîtes basées sur des propriétés communes et traite les éléments d'une boîte donnée comme interchangeables lorsque vous ne souhaitez utiliser que ces propriétés communes.

1
Matt Mitchell

Le polymorphisme consiste à traiter les choses de manière abstraite en s'appuyant sur la connaissance d'un "parent" commun (pensez à des hiérarchies comme Animal en tant que parent de Dogs and Cats).

Par exemple, tous les animaux peuvent respirer de l'oxygène, et bien qu'ils puissent chacun le faire différemment, vous pouvez concevoir une installation qui fournit de l'oxygène aux animaux pour respirer, soutenant à la fois les chiens et les chats.

En plus, vous pouvez le faire même si Animal est un identifiant "abstrait" (il n'y a pas de véritable "Animal", juste des types d'animaux).

1
Matt Mitchell

Le polymorphisme est ce que vous obtenez lorsque la même méthode s'applique à plusieurs classes. Par exemple, une chaîne et une liste peuvent avoir des méthodes "inversées". Les deux méthodes ont le même nom ("Reverse"). Les deux méthodes font quelque chose de très similaire (inverser tous les caractères ou inverser l'ordre des éléments dans la liste). Mais l'implémentation de chaque méthode "Reverse" est différente et spécifique à sa classe. (En d'autres termes, la chaîne s'inverse comme une chaîne et la liste s'inverse comme une liste.)

Pour utiliser une métaphore, vous pouvez dire "Faire le dîner" à un chef français ou à un chef japonais. Chacun effectuerait "faire le dîner" à sa manière caractéristique.

Le résultat pratique est que vous pouvez créer un "moteur inverseur" qui accepte un objet et appelle "inversé" dessus. Tant que l'objet a une méthode inverse, votre moteur d'inversion fonctionnera.

Pour étendre l'analogie avec le chef, vous pouvez créer un "Waiterbot" qui dit aux chefs de "préparer le dîner". Le Waiterbot n'a pas besoin de savoir quel type de dîner va être préparé. Il n'a même pas besoin de s'assurer qu'il parle à un chef. Tout ce qui compte, c'est que le "chef" (ou pompier, ou distributeur automatique ou distributeur d'aliments pour animaux) sache quoi faire quand on lui dit de "préparer le dîner".

En tant que programmeur, cela vous permet de réduire le nombre de lignes de code et la sécurité de type ou la liaison tardive. Par exemple, voici un exemple avec la sécurité de type et la liaison anticipée (dans un langage de type c que je crée au fur et à mesure):

class BankAccount {
    void SubtractMonthlyFee
}

class CheckingAccount : BankAccount {}

class SavingsAccount : BankAccount {}

AssessFee(BankAccount acct) {
    // This will work for any class derived from
    //   BankAccount; even classes that don't exist yet
    acct.SubtractMonthlyFee
}

main() {

    CheckingAccount chkAcct;
    SavingsAccount saveAcct;

    // both lines will compile, because both accounts
    //   derive from "BankAccount". If you try to pass in
    //   an object that doesn't, it won't compile, EVEN
    //   if the object has a "SubtractMonthlyFee" method.
    AssessFee(chkAcct);
    AssessFee(saveAcct);
}

Voici un exemple sans sécurité de type mais avec liaison tardive:

class DatabaseConnection {
    void ReleaseResources
}

class FileHandle {
    void ReleaseResources
}

FreeMemory(Object obj) {
    // This will work for any class that has a 
    //   "ReleaseResources" method (assuming all
    //   classes are ultimately derived from Object.
    obj.ReleaseResources
}

main() {

    DatabaseConnection dbConn;
    FileHandle fh;

    // You can pass in anything at all and it will
    //   compile just fine. But if you pass in an
    //   object that doesn't have a "ReleaseResources"
    //   method you'll get a run-time error.
    FreeMemory(dbConn);
    FreeMemory(fh);
    FreeMemory(acct); //FAIL! (but not until run-time)
}

Pour un excellent exemple, regardez la méthode .NET ToString (). Toutes les classes l'ont parce que toutes les classes sont dérivées de la classe Object. Mais chaque classe peut implémenter ToString () d'une manière qui a du sens pour elle-même.

EDIT: Simple! = Court, à mon humble avis

1
JPLemme

Le polymorphisme est la capacité de traiter les choses différentes comme si elles étaient la chose même en établissant une identité partagée entre elles puis en l'exploitant.

1
ljs

Le polymorphisme est le stockage de valeurs de plusieurs types dans un emplacement d'un seul type.

Notez que la plupart des autres réponses à cette question, au moment où j'écris, décrivent en fait la répartition dynamique, pas le polymorphisme.

Dynamic dispatch nécessite un polymorphisme, mais l'inverse n'est pas vrai. On pourrait imaginer un langage très similaire à Java ou C # mais dont System.Object n'avait pas de membres; le transtypage serait nécessaire avant de faire quoi que ce soit avec la valeur. Dans ce langage notionnel, il y aurait du polymorphisme, mais pas nécessairement des méthodes virtuelles ou tout autre mécanisme de répartition dynamique.

La répartition dynamique est le concept connexe mais distinct, suffisamment bien décrit dans la plupart des autres réponses. Cependant, la façon dont il fonctionne normalement dans les langages orientés objet (sélection d'une fonction basée sur le premier type d'argument ('ceci' ou 'Self')) n'est pas la seule façon dont il peut fonctionner. Envoi multiple est également possible, où la sélection est appliquée à travers les types de tous les arguments.

De même, la résolution de surcharge et l'envoi multiple sont des analogues exacts l'un de l'autre; la résolution de surcharge est une répartition multiple appliquée aux types statiques, tandis que la répartition multiple est une résolution de surcharge appliquée aux types d'exécution stockés dans des emplacements polymorphes.

1
Barry Kelly

Le polymorphisme est une fonctionnalité de langage permettant au code algorithmique de haut niveau de fonctionner sans changement sur plusieurs types de données.

Pour ce faire, les opérations appellent la bonne implémentation pour chaque type de données. Même dans un contexte OOP (selon la balise de cette question), cette "bonne implémentation" peut être résolue au moment de la compilation ou de l'exécution (si votre langue prend en charge les deux). Dans certaines langues comme Le support C++ fourni par le compilateur pour le polymorphisme d'exécution (c'est-à-dire la répartition virtuelle) est spécifique à la POO, tandis que d'autres types de polymorphisme peuvent également fonctionner sur des types de données qui ne sont pas des objets (c'est-à-dire pas struct ou class instances, mais peuvent être des types intégrés comme int ou double).

(Les types de polymorphisme pris en charge par C++ sont répertoriés et contrastés dans ma réponse: Polymorphisme en c ++ - même si vous programmez d'autres langages, c'est potentiellement instructif)

1
Tony Delroy

La façon dont j'essaie d'y penser est quelque chose qui se ressemble mais qui peut avoir des fonctionnalités différentes selon l'instance. Vous pouvez donc avoir un type

interface IJobLoader

mais selon la façon dont il est utilisé, il peut avoir des fonctionnalités différentes tout en restant identiques. Vous pouvez avoir des instances pour BatchJobLoader, NightlyJobLoader, etc.

Je suis peut-être loin.

0
Craig

La capacité d'un objet d'un certain type (par exemple, une voiture) à agir (par exemple, un frein) comme l'un d'un autre type (par exemple, un véhicule), ce qui suggère généralement une ascendance commune (par exemple, la voiture est un sous-type de véhicule) à un moment donné de la hiérarchie des types .

0
Bobby Jack

C'est juste un moyen de faire froid pour appeler un nouveau code. Vous écrivez une application qui accepte une interface "Shape" avec des méthodes que d'autres doivent implémenter (exemple - getArea). Si quelqu'un propose une nouvelle méthode pour implémenter cette interface, votre ancien code peut appeler ce nouveau code via la méthode getArea.

0
eviljack

Le terme polymorphisme peut également s'appliquer aux fonctions de surcharge. Par exemple,

string MyFunc(ClassA anA);
string MyFunc(ClassB aB);

est un exemple de polymorphisme non orienté objet.

0
tsellon

C'est une façon de traiter différentes choses qui peuvent faire quelque chose de similaire de la même manière sans se soucier de la façon dont elles le font.

Disons que vous avez un jeu avec un tas de différents types de véhicules qui circulent comme la voiture, le camion, la planche à roulettes, l'avion, etc. Ils peuvent tous s'arrêter, mais chaque véhicule s'arrête de manière différente. Certains véhicules peuvent avoir besoin de rétrograder et certains peuvent s'arrêter à froid. Le polymophisme vous permet de le faire

foreach (Vehicle v in Game.Vehicles)
{
   v.Stop();
}

La façon dont cet arrêt est implémenté est reportée aux différents véhicules afin que votre programme n'ait pas à s'en soucier.

0
Daniel Auger

C'est la capacité des objets à répondre au même message de différentes manières.

Par exemple, dans des langages tels que Smalltalk, Ruby, Objective-C, vous n'avez qu'à envoyer le message et ils répondront.

 dao  = XmlDao.createNewInstance()    #obj 1
 dao.save( data )

 dao = RdbDao.createNewnewInstance()  #obj 2
 dao.save( data )

Dans cet exemple, deux objets différents ont répondu de différentes manières aux mêmes messages: "createNewInstance () et save (obj)"

Ils agissent de différentes manières, au même message. Dans les langues ci-dessus, les classes peuvent même ne pas être dans la même hiérarchie de classes, il suffit qu'elles répondent au message.

Dans des langages tels que Java, C++, C # etc. Pour affecter l'objet à une référence d'objet, ils doivent partager la même hiérarchie de types soit en implémentant l'interface, soit en étant une sous-classe d'une classe commune.

facile .. et simple.

Le polymorphisme est de loin la caractéristique la plus importante et la plus pertinente de la programmation orientée objet.

0
OscarRyz