Le meilleur moyen est de définir la méthode abstraite dans Animal et de la surcharger dans les classes enfants. C'est comme ça que le polymorphisme fonctionne.
Pas besoin de surcharges.
public abstract class Animal {
public abstract void say();
}
public class Dog extends Animal {
@Override
public void say() {
System.out.println("Bark");
}
}
public class Cat extends Animal {
@Override
public void say() {
System.out.println("Meow");
}
}
Utilisation:
public class Main() {
public static void main(String[] args) {
List<Animals> aList = new ArrayList<>();
a.add(new Dog());
a.add(new Cat());
for (Animals a : aList)
a.say();
}
}
Sortie:
Bark
Meow
____UPDATE_1
Je voudrais ajouter som e commentaires pourquoi la surcharge de ces méthodes n'est pas une bonne idée.
Si vous ajoutez ce qui suit à votre code - il compilera:
public methodOverloaded(Animal a) {
a.say();
}
Mais cela ne fonctionnera pas comme vous vous attendez. Il appellera public methodOverloaded(Animal a)
pour tous les éléments de List
.
Pourquoi cela se produit-il?
Pour toutes les itérations de la boucle, le type de compilation du paramètre est Animal
. Le type d'exécution est différent à chaque itération, mais cela n'affecte pas le choix de la surcharge. Comme le type de compilation du paramètre est Animal
, la seule surcharge applicable est la troisième.
Le comportement de ce programme est contre-intuitif car la sélection parmi les méthodes surchargées est statique, tandis que la sélection parmi les méthodes surchargées est dynamique.
La version correcte d'une méthode substituée est choisie au moment de l'exécution, en fonction du type d'exécution de l'objet sur lequel la méthode est invoquée.
Cela peut être corrigé avec:
public methodOverloaded(Animal a) {
if (a instanceof Cat) ? "Meow" :
(a instanceof Dog) ? "Bark" : "Unknown Animal"
}
Bien sûr suggéré l'option avec des méthodes prépondérants démontre une meilleure approche et un code plus propre.
De plus, une politique prudente et prudente consiste à ne jamais exporter deux surcharges avec le même nombre de paramètres, car cela peut perturber le client de l'API. Vous pouvez toujours donner des noms différents aux méthodes au lieu de les surcharger.
Mais il y a le cas où au moins un paramètre formel correspondant dans chaque paire de surcharges a un type "radicalement différent" (quand il est clairement impossible de lancer une instance de l'un ou l'autre type) dans les deux surcharges. Par exemple, ArrayList
a un constructeur qui prend un int
et un second constructeur qui prend un Collection
. Il est difficile d'imaginer une confusion sur lequel de ces deux constructeurs sera invoqué dans n'importe quelles circonstances.
Veuillez lire ma réponse mise à jour, peut-être que ce sera plus clair maintenant. –
merci beaucoup – tommasoballardini