Avantages du polymorphisme]

quand j'ai commencé à chercher les avantages du polymorphisme, j'ai trouvé avec cette question ici. Mais ici, je n'ai pas pu trouver ma réponse. Laissez-moi vous dire ce que je veux trouver. Voici quelques cours:

class CoolingMachines{
    public void startMachine(){
        //No implementationion
    }
    public void stopMachine(){
        //No implementationion
    }
}

class Refrigerator extends CoolingMachines{
    public void startMachine(){
        System.out.println("Refrigerator Starts");
    }
    public void stopMachine(){
        System.out.println("Refrigerator Stop");
    }
    public void trip(){
        System.out.println("Refrigerator Trip");
    }
}

class AirConditioner extends CoolingMachines{
    public void startMachine(){
        System.out.println("AC Starts");
    }
    public void stopMachine(){
        System.out.println("AC Stop");
    }
}

public class PolymorphismDemo {
    CoolingMachines cm = new Refrigerator();
    Refrigerator rf = new Refrigerator();
}

maintenant ici j'ai créé deux objets dans la classe de démonstration et sont des références de Refrigerator . J'ai tout à fait compris que de l'objet rf je suis en mesure d'appeler la trip() méthode de Refrigerator , mais que la méthode sera cachée pour l'objet cm . Maintenant ma question est: pourquoi devrais-je utiliser le polymorphisme ou pourquoi devrais-je utiliser

CoolingMachines cm = new Refrigerator();

quand je suis D'accord avec

Refrigerator rf = new Refrigerator();

Est polymorphe de l'objet de l'efficacité est bonne ou de la lumière dans le poids? Quel est le but fondamental et la différence entre ces deux objets? Y a-t-il une différence entre cm.start(); et rf.start() ?

69
demandé sur Community 2012-06-18 16:14:49

9 réponses

c'est utile quand vous manipulez des listes... Un bref exemple:

List<CoolingMachines> coolingMachines = ... // a list of CoolingMachines 
for (CoolingMachine current : coolingMachines) {
    current.start();
}

ou lorsque vous voulez permettre à une méthode de fonctionner avec une sous-classe de CoolingMachines

70
répondu pgras 2012-06-19 00:53:51

dans les cas où vous êtes vraiment d'accord avec le fait de connaître la classe de béton, il n'y a aucun avantage. Cependant, dans de nombreux cas, vous voulez être en mesure d'écrire du code qui ne connaît que la classe de base ou l'interface.

par exemple, regardez Iterables dans Goyave - c'est beaucoup de méthodes qui (la plupart du temps) ne se soucient pas de l'application de Iterable est utilisé. Voulez-vous vraiment tout ce code séparément pour chaque la mise en œuvre?

où vous can code à une classe de base abstraite ou une interface, vous vous autorisez à utiliser plus tard d'autres implémentations qui partagent la même API publique, mais peuvent avoir des implémentations différentes. Même si vous ne voulez qu'une seule implémentation "production , vous pourriez vouloir des implémentations alternatives pour tester. (La mesure dans laquelle cela s'applique dépend beaucoup de la classe en question.)

56
répondu Jon Skeet 2012-06-18 12:18:39

parce que plus tard si vous voulez utiliser AirConditioner au lieu de Refrigerator pour le refroidissement, alors seul le code que vous devez changer est CoolingMachines cm = new AirConditioner();

28
répondu Naveen 2012-06-18 12:19:59

la raison pour laquelle vous voulez utiliser

CoolingMachines cm = new Refrigerator();

est que vous pouvez facilement utiliser plus tard un différent CoolingMachines . Vous avez seulement besoin de changer une ligne de code et le reste du code du travail (qu'il n'utilisera les méthodes de CoolingMachines , qui est plus général que sur une machine, comme un Refrigerator ).

ainsi pour une instance particulière de Refrigerator , les appels cm.start(); et rf.start() fonctionnent de la même façon mais cm pourrait aussi être un objet différent CoolingMachines . Et cet objet pourrait avoir une implémentation différente de start() .

16
répondu Simeon Visser 2012-06-18 12:18:19

première réponse:

Utiliser le polymorphisme pour la méthode overridding et la surcharge de méthode. Autres méthodes de classe utilisées dans la classe différente puis deux options: première méthode héritée, deuxième méthode plus écrite. Ici étendre l'interface: les utiliser, ou la méthode de mise en œuvre: logique les écrire. Polymorphisme utilisé pour la méthode, l'hérédité de classe.

deuxième réponse:

y a-t-il une différence entre cm.start(); et rf.start(); ?

Oui, les deux sont des objets complètement différents les uns des autres. Ne créez pas d'objets d'interface car Java ne supporte pas les objets d'interface. Premier objet créé pour l'interface et deuxième pour la classe Refrigerator. Deuxième objet de la droite maintenant.

7
répondu Solomon Bindavid 2012-06-18 16:22:06

la réponse la plus générale à la partie générale de votre question (Pourquoi devrais-je utiliser le polymorphisme?) est que le polymorphisme réalise quelques principes critiques de conception orientée objet, par exemple:

  • la réutilisation du code: En mettant n'importe quel code qui est commun à toutes vos 'machines de refroidissement' dans la machine de refroidissement, vous n'avez besoin d'écrire ce code qu'une seule fois et toutes les modifications à ce code se répercutent instantanément.

  • abstraction: Le cerveau humain peut seulement garder la trace de tant de choses, mais ils sont bons dans les catégories et les hiérarchies. Cela aide à comprendre ce qui se passe dans un grand programme.

  • encapsulation: chaque classe cache les détails de ce qu'il fait et juste s'appuie sur l'interface de la classe de base.

  • séparation des préoccupations: beaucoup de programmation orientée objet consiste à attribuer des responsabilités. Qui est va être en charge de qui? Les préoccupations spécialisées peuvent être classées dans des sous-classes.

ainsi le polymorphisme fait partie de l'image globale de l'oo, et les raisons de l'utiliser parfois n'ont de sens que si vous allez essayer et faire de la programmation "réelle" de l'oo.

5
répondu Scruffy 2012-06-18 21:50:05

un cas simple d'utilisation de polymorphisme est que vous pouvez avoir un éventail de machines de refroidissement où l'élément 0 est un réfrigérateur et l'élément 1 est un climatiseur, etc...

vous n'avez pas besoin de préformer des contrôles ou de s'assurer quel objet vous traitez pour appeler trip ou start etc.

cela peut être un grand avantage en prenant l'entrée d'un utilisateur et d'avoir à itérer sur tous les objets et appeler des fonctions similaires

3
répondu Simon McLoughlin 2012-06-18 12:21:05

je vais donner un exemple facile à comprendre. Disons que vous avez du json

{"a":[1,2],"sz":"text", "v":3, "f":1.2}

permet maintenant de dire programmatiquement que vous voulez lister le nom, le type et la valeur. Au lieu d'avoir un switch() pour chaque type (tableau pour une, chaîne pour sz, etc), vous pouvez juste avoir un type de base et appeler une fonction qui fait son travail. Il est également plus efficace cpu que d'utiliser un commutateur avec une douzaine de types.

puis il y a des plugins, des libs et du code étranger avec raisons de l'interface.

2
répondu 2012-06-18 21:42:38

L'utilisation de vos objets polymorphiquement aide également à créer des usines ou des familles de classes connexes qui est une partie importante de la façon dont dessin de conception D'usine est mis en œuvre. Voici un exemple très basique de polymorphic factory:

public CoolingMachine CreateCoolingMachines(string machineType)
{
    if(machineType == "ref")
        return new Refrigerator();
    //other else ifs to return other types of CoolingMachine family
}

l'utilisation de l'appel de code ci-dessus:

CoolingMachine cm = CreateCoolingMachine("AC"); //the cm variable will have a reference to Airconditioner class which is returned by CreateCoolingMachines() method polymorphically

aussi, imaginez que vous avez une méthode comme ci-dessous qui utilise le paramètre de classe de béton Refrigerator :

public void UseObject(Refrigerator refObject)
{
    //Implementation to use Refrigerator object only
}

maintenant, si vous changez au-dessus de l'implémentation de la méthode UseObject() pour utiliser le paramètre de classe de base le plus générique, le code appelant aurait avantage à passer n'importe quel paramètre polymorphiquement qui peut alors être utilisé à l'intérieur de la méthode UseObject() :

public void UseObject(CoolingMachine coolingMachineObject)
{
    //Implementation to use Generic object and all derived objects
}

le code ci-dessus est maintenant plus extensible car d'autres sous-classes pourraient être ajoutées ultérieurement à la famille des Les machines de refroidissement et les objets de ces nouvelles sous-classes fonctionneraient aussi avec le code existant.

2
répondu VS1 2012-06-19 04:36:57