Quelqu'un peut m'expliquer les avantages de polymorphisme?
Donc, je comprends assez bien comment il fonctionne, mais je ne peux pas saisir ce qui le rend utile. Vous avez encore à définir toutes les fonctions distinctes, vous devez créer une instance de chaque objet, alors pourquoi ne pas simplement appeler la fonction de cet objet vs la création de l'objet, de la création d'un pointeur vers l'objet parent et en passant les objets dérivés de référence, pour appeler une fonction? Je ne comprends pas les avantages de prendre cette étape supplémentaire.
Pourquoi ce faire:
class Parent
{
virtual void function(){};
};
class Derived : public Parent
{
void function()
{
cout << "derived";
}
};
int main()
{
Derived foo;
Parent* bar = &foo;
bar->function();
return -3234324;
}
vs ce:
class Parent
{
virtual void function(){};
};
class Derived : public Parent
{
void function()
{
cout << "derived";
}
};
int main()
{
Derived foo;
foo.function();
return -3234324;
}
Ils font exactement la même chose non? Seulement on utilise plus de mémoire et plus de confusion dans la mesure où je peux dire.
Vous devez vous connecter pour publier un commentaire.
Deux exemples pour faire la même chose mais en différentes façons.
Le premier exemple des appels
function()
en utilisant Statique de la liaison tandis que le second appelle à l'aide de Liaison Dynamique.Dans le premier cas, le compilateur connaît exactement la fonction à appeler lors de la compilation elle-même, tandis que dans le second cas, la décision à laquelle la fonction doit être appelée est faite au moment de l'exécution en fonction du type de l'objet pointé par le pointeur de classe.
Quel est l'avantage?
L'avantage, c'est plus générique et faiblement couplé code.
Imaginer une hiérarchie de classes comme suit:
Le code d'appel qui utilise ces classes, sera comme:
Où,
line_obj
,tri_obj
etc sont des objets de la Forme concrète des classesLine
,Triangle
et ainsi de suite, et ils sont stockés dans un tableau de pointeurs de type de plus généralisée de la classe de baseShape
.Cela donne une plus grande flexibilité et le couplage lâche que si vous avez besoin d'ajouter une autre forme concrète de la classe de dire
Rhombus
, le code d'appel n'a pas à changer grand-chose, car il se réfère à toutes les formes concrètes avec un pointeur sur la classe de BaseShape
. Vous n'avez qu'à faire la classe de Base pointer vers le nouveau de la classe de béton.À la sametime le code appelant peut appeler des méthodes appropriées de ces classes, parce que le
Draw()
de la méthode virtuelle dans ces classes et de la méthode à appeler sera décidé au moment de l'exécution en fonction de ce que l'objet de la classe de base d'un pointeur sur.Ci-dessus est un bon exemple de l'application Principe Ouvert Fermé de la célèbre De SOLIDES principes de design.
Dites que vous voulez quelqu'un pour se présenter au travail. Vous ne savez pas si ils ont besoin de prendre une voiture, prendre un bus, à pied, ou quoi. Vous voulez juste à se présenter au travail. Avec le polymorphisme, vous venez de leur dire de se présenter au travail et ils le font. Sans polymorphisme, vous devez comprendre comment ils doivent se rendre au travail et de les diriger vers ce processus.
Maintenant dire quelques gens commencent à prendre un Segway à travailler. Sans polymorphisme, chaque morceau de code qui raconte à quelqu'un de venir travailler a apprendre cette nouvelle façon de se rendre au travail et la façon de comprendre qui se met à travailler de cette façon et comment leur dire de le faire. Avec le polymorphisme, vous mettez ce code dans un seul endroit, dans la mise en œuvre du Segway-coureur, et tout le code qui dit aux gens d'aller travailler raconte Segway-coureurs à prendre leur Segway, même si elle n'a aucune idée de qui c'est ce qu'il fait.
Il y a beaucoup de monde réel de la programmation des analogies. Dire vous avez besoin de dire à quelqu'un qu'il y a un problème dont ils ont besoin pour étudier. Leur contact privilégié mécanisme pourrait être e-mail, ou il pourrait être un message instantané. C'est peut-être un message SMS. Avec un polymorphe de la méthode de notification, vous pouvez ajouter un nouveau mécanisme de notification sans avoir à changer tous les bits de code qui peut-être jamais besoin de l'utiliser.
polymorphisme est idéal si vous avez une liste ou un tableau d'objets qui partagent un ancêtre commun et vous qui de faire quelques chose commune avec eux, ou si vous avez une méthode redéfinie. L'exemple que j'ai appris le concept, l'utilisation de formes et de substitution de la méthode de tirage. Ils font tous des choses différentes, mais ils sont tous d'une "forme" et tous peuvent en être tirées. Votre exemple n'a pas vraiment de faire quelque chose d'utile pour justifier l'utilisation du polymorphisme
Un bon exemple de utile polymorphisme est la .NET Flux de classe. Il a de nombreuses implémentations telles que "FileStream", "MemoryStream", "GZipStream", et cætera. Un algorithme qui utilise des "Flux" au lieu de "FileStream" peuvent être réutilisés sur tous les autres types de flux avec peu ou pas de modification.
Il existe d'innombrables exemples de nice utilise de polymorphisme. Prenons l'exemple d'une classe qui représente GUI widgets. La plupart de la base de classs aurait quelque chose comme:
Qui est une fonction virtuelle pure. Cela signifie que l'ENSEMBLE de la classe qui hérite de la Base nécessaire pour la mettre en œuvre. Et bien sûr tous les widgets dans une interface graphique, besoin de dessiner eux-mêmes? C'est pourquoi vous avez besoin d'une classe de base avec toutes les fonctions qui sont communes à tous les GUI des widgets pour être défini comme pure virtuals parce qu'alors, pour tout enfant que vous allez faire comme ça:
Ensuite dans votre code, vous n'avez pas besoin de soins sur la vérification de ce type de widget, il est que vous dessinez. La responsabilité de savoir comment dessiner elle-même se trouve avec le widget (l'objet) et non pas avec vous. Si vous pouvez faire quelque chose comme ça dans votre boucle principale:
Et la partie ci-dessus en tirer toutes les widgets, peu importe s'ils sont de ChildWidget1, ChildWidget2, zone de texte, le type de Bouton.
Espère que cela aide à comprendre les avantages de polymorphisme un peu.
La réutilisation, la généralisation et de l'extensibilité.
J'ai peut-être une classe abstraite de la hiérarchie comme ceci: Véhicule > Voiture. Je peux alors simplement provenir de Voiture à mettre en œuvre des types de béton SaloonCar, CoupeCar etc. - Je mettre en œuvre le code commun dans les classes de base abstraites. J'ai peut-être également construit des autre code qui est couplé avec la Voiture. Mon SaloonCar et CoupeCar sont les deux Voitures afin que je puisse les transmettre à ce code client sans altération.
Considère maintenant que j'ai peut-être une interface; IInternalCombustionEngine et une classe combinée avec, disons Garage (fictive je sais, rester avec moi). Je peux implémenter cette interface sur les classes définies dans une catégorie distincte des hiérarchies. E. G.
Donc, je peux maintenant affirmer qu'un objet instance de FordCortina est un Véhicule, c'est une Voiture, c'est un IInternalCombustionEngine (ok inventé de nouveau, mais vous obtenez le point) et c'est aussi un véhicule de tourisme. C'est une puissante construction.
La poly dans polymorphes signifie plus d'un. En d'autres termes, le polymorphisme n'est pas pertinente, sauf s'il existe plus d'une fonction dérivée.
Dans cet exemple, j'ai deux fonctions dérivées. L'un d'eux est sélectionné sur la base
mode
variable. Notez que leagnostic_function()
ne sais pas qui a été sélectionné. Néanmoins, il appelle la bonne version defunction()
.Donc le point de polymorphisme, c'est que votre code n'a pas besoin de savoir qui de la classe dérivée est utilisée. La sélection spécifique de la classe à instancier peut être localisée à un seul point dans le code. Cela rend le code beaucoup plus propre et plus facile à développer et à maintenir.
Polymorphisme est l'Un des principes de la programmation orientée objet. Avec le polymorphisme vous pouvez choisir plusieurs comportement dans l'exécution. Dans votre exemple, vous avez une mise en œuvre d'un Parent, si vous avez plus de la mise en œuvre, vous pouvez choisir l'un par les paramètres de l'exécution. le polymorphisme de l'aide pour le découplage des couches de l'application. dans votre échantillon de la troisième partie l'utilisation de cette structers puis il voir interface Parent seul et ne savez pas mise en œuvre dans l'exécution afin de tiers independ des implémentations de l'interface Parent. Vous pouvez voir d'Injection de Dépendance schéma pour mieux desing.
Juste un point de plus à ajouter. Le polymorphisme est nécessaire de mettre en œuvre au moment de l'exécution des plugins. Il est possible d'ajouter des fonctionnalités à un programme au moment de l'exécution. En C++, les classes dérivées peuvent être mis en œuvre comme objet partagé bibliothèques. Le temps d'exécution du système peut être programmé pour regarder un répertoire de la bibliothèque, et si un objet partagé s'affiche, il relie il en et pouvez commencer à l'appeler. Cela peut aussi être fait en Python.
Disons que mon
School
classe a uneducate()
méthode. Cette méthode accepte les seules personnes qui peuvent apprendre. Ils ont différents styles d'apprentissage. Quelqu'un saisit, quelqu'un vient de tasses vers le haut, etc.Maintenant, disons que j'ai des garçons, des filles, des chiens et des chats autour de l'École, de la classe. Si
School
veut les éduquer, je devrais écrire des méthodes différentes pour les différents objets, en vertu deSchool
.Au lieu de cela, les gens différents Objets (les garçons,les filles , chats..) de mettre en œuvre la Ilearnable interface. Ensuite, le
School
classe n'ont pas à s'inquiéter de ce qu'il a pour instruire.L'école juste pour écrire un
méthode.
J'ai écrit les chats et les chiens, car ils pourraient vouloir visiter les différents type d'école. Tant qu'il est certain type d'école (PetSchool : l'École) et ils peuvent Apprendre, ils peuvent être éduqués.