Supposons que je travaille sur un système existant, assez grand. J'ai un objet, myObject
de classe MyClass
(par exemple, supposons que je travaille en Java). myObject
est une composition contenant Collection
, disons, un List
et d'autres objets qui (je pense) ne sont pas pertinents. Il contient des méthodes déléguées qui servent simplement à faire appel aux méthodes de celui- List
ci, afin de s'assurer List
qu'il ne soit pas exposé (désolé si j'ai une mauvaise terminologie).
Disons que List
c'est un List<String>
mais, pour une raison quelconque, la méthode d'accès principale est une méthode de masque pour la classe SomeOtherClass
. Si je voulais insérer une nouvelle paire de valeurs dans mon List
, alors j'aurais un objet SomeOtherClass
appelé someObject
. J'appellerais myObject.insert(someObject)
et à l'intérieur de la insert
méthode, il y aurait de la magie qui récupérerait un String
pour le mettre dans le List<String>
.
Supposons maintenant que je n'ai qu'une String
valeur et aucun SomeOtherClass
objet à insérer. En supposant que je ne peux pas modifier la insert
méthode car cela casserait tout dans ce système. Dois-je alors surcharger la insert
méthode? Ou dois-je créer un nouvel objet à SomeOtherClass
chaque fois que je veux appeler insert
?
Je suppose que si je le surchargeais, ça ressemblerait à quelque chose comme ça ...
public void insert(String s) {
...
}
public void insert(SomeOtherObject obj) {
this.insert(obj.magicStringMethod());
}
(Cet exemple est un puzzle artificiel basé sur une situation similaire (légèrement plus complexe) concernant la surcharge que j'ai rencontrée hier. Je vais l'étendre s'il y a quelque chose qui n'était pas clair)
Serait-ce un endroit approprié pour surcharger une méthode? Sinon, quand devrais-je surcharger une méthode?
magicStringMethod()
dans mon exemple, obtiendrait, dans mon cas, uneString
représentation deSomeOtherObject
ce qui était un objet de domaine.Réponses:
Vous surchargez lorsque vous souhaitez prendre en charge différents types:
ou pour prendre en charge une interface progressive utilisant différentes listes de paramètres:
Vous pouvez même devenir un peu fou et prendre en charge les deux types différents ET une interface progressive, mais vous devez garder à l'esprit que vous devez éviter de créer des variations de comportement entre les méthodes surchargées. Chaque méthode surchargée doit être fonctionnellement la même que les autres dans un groupe surchargé, sinon il sera difficile de savoir comment, quand ou pourquoi le comportement est modifié. Si vous voulez que deux fonctions fassent quelque chose de complètement différent, vous devez les nommer en conséquence.
la source
Je dirais que la surcharge est appropriée lorsque les deux méthodes sont sémantiquement équivalentes. Pour voler des exemples de dukeofgaming:
Ceux-ci sont surchargés de manière appropriée:
Ce ne sont pas:
C'est un exemple extrême (si vous ne l'avez pas saisi, la dernière méthode soustrait en fait au lieu d'ajouter), mais l'idée est que si vous avez plusieurs méthodes dans une classe avec le même nom, elles devraient se comporter de manière cohérente.
Dans votre exemple, d'après les informations fournies, ils semblent équivalents (puisque l'un appelle l'autre) et je pense qu'il est raisonnable de les surcharger. Cela ne peut pas faire de mal de demander à une personne plus âgée de votre équipe si vous n'êtes pas sûr de savoir si la méthode doit être ajoutée, mais si vous l'ajoutiez, j'utiliserais le même nom (c'est-à-dire que je la surchargerais).
la source
Essentiellement, les paramètres de la méthode dictent le comportement de la méthode.
Un exemple rapide serait:
Si vous passez la méthode sum (a, b) à quelques entiers, elle sait qu'elle doit appeler la première implémentation, car l'appel de méthode coïncide avec la signature de la méthode (c'est-à-dire que la double somme (double, double) ne fonctionnera pas si vous donnez méthode de somme deux entiers).
La signature de l'appel doit correspondre aux implémentations disponibles, donc essayer d'appeler sum (chaîne, chaîne) ne fonctionnera que si vous avez ceci:
tl; dr: pour que la classe gère la bonne méthode en fonction des paramètres que vous donnez à une méthode du même nom.
Lors de l'héritage, il est appelé remplacement
Un bon exemple de cet autre scénario est lorsque vous souhaitez modifier le comportement par défaut d'une classe en l'héritant, et en particulier lorsque vous avez quelque chose de similaire au modèle de méthode de modèle, où vous avez chaque étape d'un algorithme implémenté dans une méthode.
Imaginez que vous ayez
class Robot
et une méthode appeléefireAtTarget(Target target)
... qui appelle lesfireWeaponA(target); fireWeaponB(target); fireWeaponC(target);
uns après les autres. Vous voulez également avoir une collection appelée robot_army à laquelle vous ne pouvez ajouter que des objets de la classe Robot. Le robot tire des mitrailleuses par défaut dans sesfireWeaponX()
méthodes.Ensuite, vous voulez avoir
class LazorRobot
etclass MissileRobot
, implémentez-vous Robot à nouveau?, Non, il suffit que LazorRobot et MissileRobot héritent de Robot, et surchargent chaquefireWeaponX()
méthode pour utiliser Lazorz ou des missiles et vous aurez le même comportement avec différentes armes, sans avoir à réimplémenter le reste des méthodes.tl; dr: Pour que le comportement de la méthode dépende de la classe sans casser l'interface (robot_army accepte uniquement Robot, mais accepte par extension toutes les classes qui héritent de Robot).
la source
when inheriting
section n'est probablement pas nécessaire. :)sum(String, String)
etsum(int, int)
?