Question

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

On trouve beaucoup d’informations sur le sujet sur Internet et dans des livres, comme dans Type polymorphisme . Mais essayons de le rendre aussi simple que possible.

Était-ce utile?

La solution

Ceci provient de ma réponse à une question similaire. Voici un exemple de polymorphisme dans 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 de la méthode MakeNoise () dans une implémentation particulière.

Autres conseils

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

Chaque boîte de conserve munie d’un simple couvercle anti-pop s’ouvre de la même manière.
En tant qu'être humain, vous savez que vous pouvez trouver Open () comme vous pouvez le trouver.

Une fois ouvertes, toutes les boîtes de conserve ne se comportent pas de la même manière.
Certaines contiennent des noix, certaines contiennent de faux serpents qui sortent.
Le résultat dépend du type de canette, si celle-ci é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 de dialogue et que vous obtiendrez une sorte de résultat 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'appelons

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

L’humain est l’utilisateur / appelant.
Open () est la fonction virtuelle / polymorphe.
"Peut" est la classe de base abstraite.
CanOfNuts et CanOfSnakes sont les enfants polymorphes de "Can". classe.
Chaque boîte peut être ouverte, mais ce qu'elle fait spécifiquement et quel type de contenu elle retourne sont définis par son type.
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 le fait de faire éclater des serpents au visage) sont décidés par la canette spécifique.

La description la plus simple du polymorphisme est la suivante: c’est un moyen de réduire les déclarations if / switch .

Il présente é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érons la classe Stream dans .NET. Sans polymorphisme, il s'agirait d'une seule classe massive dans laquelle chaque méthode implémenterait une instruction switch du type:

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.
    }
}

À la place, nous permettons au moteur d'exécution d'effectuer la commutation pour nous plus efficacement, 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
    }
}

Poly: beaucoup de
Morphisme: formes / formes

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

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

Le botteur? Vous les mangez différemment! Vous pelez les oranges, mais pas les pommes.

La mise en œuvre diffère donc, mais le résultat final est identique, vous mangez le fruit .

S'il marche comme un canard et que les charlatans sont comme un canard, vous pouvez le traiter comme un canard partout où vous avez besoin d'un canard.

Cet article est vraiment meilleur

Le polymorphisme permet aux objets de "Regarder". les mêmes, mais se comportent de différentes manières. L’exemple habituel est de prendre une classe de base d’animal avec une méthode Speak (), une sous-classe de chien émettrait une écorce alors 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 faire comprendre Le polymorphisme surcharge et surcharge

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

Manière la plus simple de le décrire: un verbe pouvant s’appliquer à plusieurs types d’objets.

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

Le polymorphisme consiste à traiter les choses de manière abstraite en s’appuyant sur la connaissance d’un "parent" commun. (pensez aux hiérarchies comme Animal en tant que parent de chiens et de chats).

Par exemple, tous les animaux peuvent respirer de l'oxygène et, s'ils le font chacun différemment, vous pouvez concevoir une installation fournissant de l'oxygène à la respiration des animaux, qui soutient les chiens et les chats.

Comme petit extra, vous pouvez le faire même si Animal est un "abstrait" identifiant (il n’existe pas de véritable "animal", mais uniquement des types d’animaux).

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

Notez que la plupart des autres réponses à cette question, au moment de ma rédaction, décrivaient en réalité une répartition dynamique, et non un polymorphisme.

L'envoi dynamique 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’a aucun membre; le transtypage serait nécessaire avant de faire quoi que ce soit avec la valeur. Dans ce langage théorique, il y aurait du polymorphisme, mais pas nécessairement des méthodes virtuelles, ni aucun autre mécanisme d'envoi dynamique.

La répartition dynamique est le concept associé mais distinct, bien décrit dans la plupart des autres réponses. Cependant, la façon dont cela fonctionne normalement dans les langages orientés objet (sélectionner une fonction sur la base du premier type d'argument ('this' ou 'Self')) n'est pas la seule façon de fonctionner. La La répartition multiple est également possible, la sélection étant appliquée à tous les types d'arguments.

De même, la résolution de la surcharge et la répartition multiple sont des analogues exacts les uns des autres; La résolution de surcharge correspond à une répartition multiple appliquée à des types statiques, tandis que la répartition multiple correspond à une résolution de surcharge appliquée à des types d'exécution stockés dans des emplacements polymorphes.

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

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

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 " Inversé " méthodes. 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 la mise en œuvre de chaque " Reverse " La méthode 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 "Préparez le dîner". à un chef français ou à un chef japonais. Chacun effectuerait "préparer le dîner" à leur manière propre.

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

Pour étendre l'analogie du chef, vous pouvez créer un "Waiterbot". qui invite les chefs à "préparer le dîner". Waiterbot n'a pas besoin de savoir quel type de dîner sera préparé. Il n'est même pas nécessaire de s'assurer de parler à un chef. Ce qui compte, c’est que le & chef; chef " (ou un pompier, ou un distributeur automatique, ou un distributeur d'aliments pour animaux domestiques) sait quoi faire quand on lui dit de "préparer le dîner".

En tant que programmeur, cela vous achète moins de lignes de code et une sécurité de type ou une liaison tardive. Par exemple, voici un exemple avec type safety et early binding (dans un langage de type c que je compose 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 une 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, car toutes les classes sont dérivées de la classe Object. Mais chaque classe peut implémenter ToString () d’une manière qui ait un sens pour elle-même.

EDIT: Simple! = court, à mon humble avis

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

Pour ce faire, vous devez vous assurer que les opérations appellent la bonne implémentation pour chaque type de données. Même dans un contexte de POO (selon l'étiquette de cette question), cette "mise en œuvre correcte" peut être résolu au moment de la compilation ou de l'exécution (si votre langage prend en charge les deux). Dans certains langages tels que C ++, la prise en charge par le compilateur du polymorphisme au moment de l'exécution (distribution virtuelle) est spécifique à la POO, alors 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 classe , mais peuvent être des types intégrés tels que int ou double ).

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

La façon dont j'essaye de penser est quelque chose qui a l'air identique mais peut avoir des fonctionnalités différentes selon l'instance. Donc, vous pouvez avoir un type

interface IJobLoader

mais selon l'utilisation qui en est faite peut avoir différentes fonctionnalités tout en conservant le même aspect. Vous pouvez avoir des instances pour BatchJobLoader, NightlyJobLoader, etc.

Peut-être que je suis très loin.

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.

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, il vous suffit d'envoyer le message et ils vous 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 la même manière aux mêmes messages: "createNewInstance () and save (obj)"

Ils agissent de différentes manières, au même message. Dans les langages 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 attribuer 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 faisant partie d'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.

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.

Supposons que vous jouez avec plusieurs types de véhicules tels que voiture, camion, planche à roulettes, 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 d'autres 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 mis en œuvre est reportée sur les différents véhicules afin que votre programme ne s'en préoccupe pas.

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

La capacité d’un objet (par exemple, une voiture) à agir (par exemple, un frein) comme un autre type (par exemple, un véhicule) suggérant généralement une ascendance commune (par exemple, la voiture est un sous-type de véhicule) en la hiérarchie des types.

Le polymorphisme est la solution orientée objet au problème du passage d’une fonction à une autre. En C, vous pouvez faire

 void h() { float x=3.0; printf("%f", x); }
 void k() { int y=5; printf("%i", y); }
 void g(void (*f)()) { f(); }
 g(h);  // output 3.0
 g(k);  // output 5

En C, les choses se compliquent si la fonction dépend de paramètres supplémentaires. Si les fonctions h et k dépendent de différents types de paramètres, vous rencontrez des problèmes et vous devez utiliser la transtypage. Vous devez stocker ces paramètres dans une structure de données et passer un pointeur sur cette structure de données à g qui le transmet à h ou k. h et k transforment le pointeur en pointeur sur la structure appropriée et décompactent les données. Très salissant et très dangereux à cause d'éventuelles erreurs de casting:

 void h(void *a) { float* x=(float*)a; printf("%f",*x); }
 void k(void *a) { int* y=(int*)a; printf("%i",*y); }
 void g(void (*f)(void *a),void *a) { f(a); }
 float x=3.0;
 int y=5;
 g(h,&x); // output x
 g(k,&y); // output y

Ils ont donc inventé le polymorphisme. h et k sont promus en classes et les fonctions réelles en méthodes, les paramètres sont des variables membres de la classe respective, h ou k. Au lieu de transmettre la fonction, vous transmettez une instance de la classe contenant la fonction souhaitée. L’instance contient ses propres paramètres.

class Base { virtual public void call()=0; }
class H : public Base { float x; public void call() { printf("%f",x);} } h;
class K : public Base { int y; public void call() { printf("%i",y);} } k;
void g(Base &f) { f.call(); };
h.x=3.0;
k.y=5;
g(h); // output h.x
g(k); // output k.x
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top