377 votes

Polymorphisme vs surcharge vs surcharge

En termes de Java, quand quelqu'un demande :

qu'est-ce que le polymorphisme ?

Serait-ce surcharge o Remplacement de serait une réponse acceptable ?

Je pense qu'il y a un peu plus que ça.

Si vous avez une classe de base abstraite qui définit une méthode sans l'implémenter, et que vous définissez cette méthode dans la sous-classe, est-ce que cela reste une surcharge ?

Je pense surcharge n'est pas la bonne réponse, c'est sûr.

0 votes

Les réponses ci-dessous expliquent très bien le polymorphisme. Mais j'ai une forte objection à dire que la surcharge est un type de polymorphisme, que j'ai essayé de justifier dans ma question et réponse qui se concentre en fait sur la surcharge est polymorphisme ou non. J'ai essayé de justifier la réponse de @The Digital Gabeg présente dans ce fil. Voir Élaboration : La surcharge des méthodes est une liaison statique/du temps de compilation mais pas le polymorphisme. Est-il correct de corréler la liaison statique avec le polymorphisme ?

947voto

Chris Cudmore Points 11133

La manière la plus claire d'exprimer le polymorphisme est d'utiliser une classe (ou une interface) de base abstraite.

public abstract class Human{
   ...
   public abstract void goPee();
}

Cette classe est abstraite car le goPee() n'est pas définissable pour les humains. Elle n'est définissable que pour les sous-classes Male et Female. De plus, Human est un concept abstrait. Vous ne pouvez pas créer un humain qui ne soit ni Male ni Female. Il faut que ce soit l'un ou l'autre.

Nous différons donc l'implémentation en utilisant la classe abstraite.

public class Male extends Human{
...
    @Override
    public void goPee(){
        System.out.println("Stand Up");
    }
}

et

public class Female extends Human{
...
    @Override
    public void goPee(){
        System.out.println("Sit Down");
    }
}

Maintenant on peut dire à une pièce entière pleine d'humains d'aller faire pipi.

public static void main(String[] args){
    ArrayList<Human> group = new ArrayList<Human>();
    group.add(new Male());
    group.add(new Female());
    // ... add more...

    // tell the class to take a pee break
    for (Human person : group) person.goPee();
}

En exécutant ceci, on obtiendrait :

Stand Up
Sit Down
...

46 votes

@yuudachi. J'ai eu l'idée de cet exemple en enseignant une classe. La classe canonique "Compte bancaire" n'exprimait pas vraiment le caractère "abstrait" de la classe de base. L'autre exemple canonique (Animal, faire du bruit) était trop abstrait pour être compris. Je cherchais une base unique avec des sous-classes trop évidentes. En fait, goPee() était le seul exemple que j'ai trouvé qui n'était pas sexiste ou stéréotypé. (bien qu'en classe, j'ai imprimé "au fond du couloir à gauche" au lieu de se lever ou s'asseoir).

110 votes

Cet exemple met également bien en évidence la difficulté d'utiliser un système hiérarchique pour décrire les systèmes biologiques. Certains humains, comme les très jeunes, font pipi dans presque n'importe quelle position - et on ne peut pas facilement dire aux bébés d'allerPee(). Certains êtres humains sont intersexués, ce qui rend les étiquettes biologiques "homme" ou "femme" plutôt mal définies ; les significations sociales sont encore plus complexes. En tant qu'exemple d'enseignement, il montre comment les hypothèses de modélisation peuvent avoir des résultats négatifs, comme l'implication qu'une personne (par exemple, un étudiant en programmation OO) qui est incontinente ou intersexuée n'est pas réellement humaine.

10 votes

Je peux penser à au moins une poignée d'humains qui réfuteraient votre thèse "vous ne pouvez pas créer un humain qui ne soit ni mâle ni femelle", bien que ce serait toujours vrai pour votre code... mauvaise abstraction je suppose que je dis... ;)

105voto

The Digital Gabeg Points 1581

Polymorphisme est la capacité d'une instance de classe à se comporter comme si elle était une instance d'une autre classe dans son arbre d'héritage, le plus souvent une de ses classes ancêtres. Par exemple, en Java, toutes les classes héritent d'Object. Par conséquent, vous pouvez créer une variable de type Object et lui affecter une instance de n'importe quelle classe.

Un site contourner est un type de fonction qui apparaît dans une classe qui hérite d'une autre classe. Une fonction de surcharge "remplace" une fonction héritée de la classe de base, mais le fait de telle sorte qu'elle est appelée même lorsqu'une instance de sa classe prétend être d'un type différent grâce au polymorphisme. En vous référant à l'exemple précédent, vous pourriez définir votre propre classe et surcharger la fonction toString(). Comme cette fonction est héritée d'Object, elle sera toujours disponible si vous copiez une instance de cette classe dans une variable de type Object. Normalement, si vous appelez toString() sur votre classe alors qu'elle prétend être un Object, la version de toString qui sera effectivement exécutée est celle définie sur Object lui-même. Cependant, comme la fonction est une surcharge, la définition de toString() de votre classe est utilisée même si le véritable type de l'instance de la classe est caché par le polymorphisme.

Surcharge de travail est l'action de définir plusieurs méthodes portant le même nom, mais avec des paramètres différents. Elle n'est pas liée à la surcharge ou au polymorphisme.

9 votes

C'est vieux mais le polymorphisme n'implique pas que l'autre classe doit être dans l'arbre d'héritage. C'est le cas en Java si l'on considère que les interfaces font partie de l'arbre d'héritage, mais pas en Go, où les interfaces sont implémentées implicitement.

6 votes

En fait, vous n'avez pas du tout besoin de classes pour le polymorphisme.

4 votes

Je suis un débutant, et corrigez-moi si je me trompe, mais je ne dirais pas que la surcharge n'est pas liée au polymorphisme. Au moins en Java, le polymorphisme est lorsque la mise en œuvre est choisie en fonction du type de l'appelant, et la surcharge est lorsque la mise en œuvre est choisie en fonction du type des paramètres, n'est-ce pas ? Le fait de voir la similitude entre les deux m'aide à comprendre.

64voto

manoj Points 71

Le polymorphisme signifie plus d'une forme, le même objet effectuant différentes opérations selon les besoins.

Le polymorphisme peut être réalisé de deux manières, à savoir

  1. Remplacement de la méthode
  2. Surcharge des méthodes

Surcharge des méthodes signifie écrire deux ou plusieurs méthodes dans la même classe en utilisant le même nom de méthode, mais le passage des paramètres est différent.

Remplacement de la méthode signifie que nous utilisons les noms des méthodes dans les différentes classes, c'est-à-dire que la méthode de la classe parent est utilisée dans la classe enfant.

En Java, pour réaliser le polymorphisme, une variable de référence de la super classe peut contenir l'objet de la sous-classe.

Pour réaliser le polymorphisme, chaque développeur doit utiliser les mêmes noms de méthodes dans le projet.

6 votes

+1 pour une bonne réponse. La réponse acceptée n'explique qu'un seul type de polymorphisme. Cette réponse est complète.

3 votes

Le polymorphisme est un paradigme (OOP), mais la surcharge et la surcharge sont des facilités de langage.

0 votes

Le polymorphisme peut également être réalisé par le type générique.

46voto

Patrick McElhaney Points 22093

La surcharge et la surcharge sont toutes deux utilisées pour réaliser le polymorphisme.

Vous pourriez avoir une méthode dans une classe qui est Remplacé par dans un ou plusieurs sous-classes. La méthode fait différentes choses en fonction de la classe classe a été utilisée pour instancier un objet.

    abstract class Beverage {
       boolean isAcceptableTemperature();
    }

    class Coffee extends Beverage {
       boolean isAcceptableTemperature() { 
           return temperature > 70;
       }
    }

    class Wine extends Beverage {
       boolean isAcceptableTemperature() { 
           return temperature < 10;
       }
    }

Vous pouvez aussi avoir une méthode qui est surchargé avec deux ou plusieurs séries d'arguments. La méthode fait différentes choses en fonction du type(s) d'argument(s) transmis.

    class Server {
        public void pour (Coffee liquid) {
            new Cup().fillToTopWith(liquid);
        }

        public void pour (Wine liquid) {
            new WineGlass().fillHalfwayWith(liquid);
        }

        public void pour (Lemonade liquid, boolean ice) {
            Glass glass = new Glass();
            if (ice) {
                glass.fillToTopWith(new Ice());
            }
            glass.fillToTopWith(liquid);
        }
    }

0 votes

Je suppose qu'il a été rejeté parce qu'historiquement, la surcharge de méthodes n'est pas considérée comme faisant partie du polymorphisme dans le paradigme orienté objet. La surcharge de méthodes et le polymorphisme sont deux caractéristiques ortogonales et indépendantes d'un langage de programmation.

7 votes

Comme je l'ai dit dans ma réponse ici, je ne suis pas d'accord - les deux caractéristiques ne sont pas orthogonales, mais sont étroitement liées. Polymorphisme != Héritage. Vous avez mon vote positif.

3 votes

En d'autres termes, polymorphisme de type vs. polymorphisme ad-hoc. Je vote en faveur de cette réponse, même si elle n'est pas aussi complète qu'elle le devrait, car elle indique correctement que la surcharge et la surcharge sont toutes deux liées au polymorphisme. Dire que le polymorphisme dans les langages de POO ne peut être réalisé que par l'héritage de classes est tout simplement faux - nous devrions nous rappeler qu'il y a d'autres langages de POO que Java et C++, où l'on peut utiliser des concepts comme le dispatching multiple, le polymorphisme ad hoc, le polymorphisme paramétrique et ainsi de suite.

42voto

Mark A. Nicolosi Points 11859

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 fonction Main ne connaît pas le type de l'animal et dépend du comportement de la méthode MakeNoise() d'une implémentation particulière.

Edit : On dirait que Brian m'a devancé. C'est drôle que nous ayons utilisé le même exemple. Mais le code ci-dessus devrait aider à clarifier les concepts.

0 votes

C'est un exemple de polymorphisme d'exécution. Le polymorphisme à la compilation est également possible grâce à la surcharge des méthodes et aux types génériques.

0 votes

Forme -> Parallélogramme -> Rectangle -> Carré

0 votes

@yankee2905 dans ce cas, je pense que vous pourriez utiliser des interfaces, puisqu'une classe peut implémenter plusieurs interfaces.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X