Supposons que j'ai deux classes: Animal et Dog. Dog est une sous-classe de Animal. Je fais le code suivant:
Animal a = new Dog();
Maintenant, je peux appeler des méthodes de la classe Dog via la variable a.
Mais ma question est la suivante: si je peux appeler toutes les méthodes d’Animal à travers les objets Dog (héritage), pourquoi utiliser le principe du polymorphisme? Je peux simplement déclarer:
Dog d = new Dog();
Avec cette déclaration, vous pouvez utiliser toutes les méthodes d’Animal et de chien. Alors, pourquoi utiliser le polymorphisme? Merci beaucoup pour votre réponse.
En Java, les concepts de polymorphisme et d'héritage sont "soudés"; en général, il ne doit pas en être ainsi:
Il y a des langues où l'héritage est découplé du polymorphisme:
virtual
)Pour revenir à Java, la raison d'utiliser le polymorphisme est de découpler votre code des détails de la mise en œuvre de ses contreparties: par exemple, si vous pouvez écrire une méthode Feed(Animal animal)
qui fonctionne pour toutes sortes d'animaux, la méthode restera applicable lorsque vous ajoutez plus de sous-classes ou d’implémentations de Animal
. Ceci contraste avec la méthode Feed(Dog dog)
qui serait étroitement liée aux chiens.
Jusqu'au
Dog d = new Dog();
selon la déclaration, il n'y a pas de raison générale de l'éviter si vous savez que le reste de votre méthode traite spécifiquement des chiens. Cependant, dans de nombreux cas, ce n'est pas le cas par la suite: par exemple, votre classe ou vos méthodes seraient souvent insensibles à l'implémentation exacte, par exemple
List<Integer> numbers = new ArrayList<Integer>();
Dans de tels cas, vous pouvez remplacer new ArrayList<Integer>()
par new LinkedList<Integer>()
et know que votre code va compiler. En revanche, si votre liste numbers
avait été déclarée en tant que ArrayList<Integer> numbers
, un tel basculement n'aurait peut-être pas été une certitude.
Cela s'appelle "programmation sur une interface". Il y a un très bon réponse sur Stack Overflow qui l'explique.
Vous pouvez avoir d'autres implémentations de la classe Animal
, telles que Cat
. Alors tu peux dire
Animal a = new Dog();
Animal b = new Cat();
Vous pouvez appeler des méthodes de la classe Animal
sans vous soucier de son implémentation réelle et polymorphism appellera la bonne méthode. Par exemple.
a.speak(); // "Woof"
b.speak(); // "Meow"
En réalité, ce n'est pas "Polymorphisme vs Héritage" mais "Polymorphisme utilisant l'Héritage".
Le polymorphisme vous permet d’écrire une méthode qui fonctionne pour tout Animal
:
public void pet(Animal animal) {
...
}
Cette méthode accepterait Dog
, Cat
, etc., y compris les sous-classes de Animal
qui n'ont pas encore été écrites.
Si la méthode prenait Dog
, elle ne fonctionnerait pas pour Cat
etc.
Si vous êtes certain que ce sera toujours un chien, il n'y a aucune raison de le faire. Vous pouvez également utiliser Dog d = new Dog (); comme vous l'avez décrit. Mais disons que vous avez utilisé une méthode au lieu d'un constructeur. La méthode renvoyait un animal et vous ne sauriez pas quelle implémentation d’animal vous obtiendriez. Vous pourrez toujours utiliser les mêmes méthodes sur l'animal (même s'il s'agit d'un chien, d'un chat d'éléphant, etc.).
Pour des raisons d'extensibilité, l'héritage simplifie les choses. Lorsque vous voulez créer un éléphant ou un chat qui partage également certaines méthodes animales, vous pouvez facilement les obtenir en prenant animal comme classe supérieure.
Normalement, la question que vous avez posée est plus similaire à Inheritance vs Composition :). Un exemple plus concret de pourquoi il est bon d’utiliser le polymorphisme est, par exemple, l’utilisation du modèle de conception de stratégie. Vous pouvez avoir plusieurs implémentations de TaxPolicy: UsaTaxPolicy, CanadaTaxPolicy, EuTaxPolicy, etc. Si vous avez la méthode CalculateFinalPrice, qui doit également calculer la taxe, vous injectez la bonne implémentation et un bon calcul est exécuté, peu importe si vous avez passé Usa, Canada ou Mise en œuvre de l'UE.
l'héritage est le polymorphisme dynamique. Je veux dire lorsque vous supprimez l'héritage, vous ne pouvez plus remplacer.