Angenommen, ich arbeite an einem vorhandenen, relativ großen System. Ich habe ein Objekt myObject
der Klasse MyClass
(zum Beispiel nehme ich an, ich arbeite in Java). myObject
ist eine Komposition Collection
, die beispielsweise a List
und andere Objekte enthält, die (glaube ich) irrelevant sind. Es enthält Delegate-Methoden, die nur dazu dienen, die Methoden aufzurufen, aus denen List
es besteht, um sicherzustellen, dass List
es nicht verfügbar gemacht wird (Entschuldigung, wenn meine Terminologie falsch ist).
Nehmen wir an, dies List
ist eine, List<String>
aber aus irgendeinem Grund ist die Hauptzugriffsmethode eine Maskenmethode für die Klasse SomeOtherClass
. Wenn ich ein neues Wertepaar in mein einfügen wollte, List
hätte ich ein Objekt SomeOtherClass
namens aufgerufen someObject
. Ich würde anrufen myObject.insert(someObject)
und innerhalb der insert
Methode würde es etwas Magie geben, die ein abrufen würde String
, um es in das zu setzen List<String>
.
Angenommen, ich habe nur einen String
Wert und kein SomeOtherClass
Objekt zum Einfügen. Angenommen, ich kann die insert
Methode nicht ändern , da sie alles in diesem System beschädigen würde. Dann sollte ich die insert
Methode überladen ? Oder sollte ich SomeOtherClass
jedes Mal ein neues Objekt erstellen, wenn ich anrufen möchte insert
?
Ich denke, wenn ich es überladen würde, würde es ungefähr so aussehen ...
public void insert(String s) {
...
}
public void insert(SomeOtherObject obj) {
this.insert(obj.magicStringMethod());
}
(Dieses Beispiel ist ein erfundenes Rätsel, das auf einer ähnlichen (etwas komplexeren) Situation in Bezug auf Überlastung basiert, auf die ich gestern gestoßen bin. Ich werde es erweitern, wenn etwas unklar ist.)
Wäre dies ein geeigneter Ort, um eine Methode zu überladen? Wenn nicht, wann sollte ich eine Methode überladen?
magicStringMethod()
In meinem Beispiel würde in meinem Fall eineString
Darstellung erhalten, beiSomeOtherObject
der es sich um ein Domänenobjekt handelt.Antworten:
Sie überlasten, wenn Sie verschiedene Typen unterstützen möchten:
oder um eine progressive Schnittstelle mit verschiedenen Parameterlisten zu unterstützen:
Sie werden vielleicht sogar ein bisschen verrückt und unterstützen sowohl verschiedene Typen als auch eine progressive Benutzeroberfläche, aber Sie sollten bedenken, dass Sie vermeiden müssen, dass sich das Verhalten zwischen überladenen Methoden ändert. Jede überladene Methode sollte funktional mit den anderen in einer überladenen Gruppe identisch sein, da sonst unklar ist, wie, wann oder warum das Verhalten variiert wird. Wenn Sie möchten, dass zwei Funktionen etwas völlig anderes tun, sollten Sie sie entsprechend benennen.
quelle
Ich würde sagen, dass eine Überladung angemessen ist, wenn beide Methoden semantisch äquivalent sind. Um aus den Beispielen von dukeofgaming zu stehlen:
Diese sind entsprechend überlastet:
Diese sind nicht:
Das ist ein extremes Beispiel (wenn Sie es nicht verstanden haben, subtrahiert die letzte Methode tatsächlich anstatt zu addieren), aber die Idee ist, dass sich mehrere Methoden in einer Klasse mit demselben Namen konsistent verhalten sollten, wenn Sie sie haben.
In Ihrem Beispiel scheinen die angegebenen Informationen gleichwertig zu sein (da einer den anderen anruft), und ich halte es für vernünftig, sie zu überladen. Es kann nicht schaden, jemanden zu fragen, der älter in Ihrem Team ist, wenn Sie sich nicht sicher sind, ob die Methode hinzugefügt werden soll, aber wenn Sie sie hinzufügen würden, würde ich denselben Namen verwenden (dh ich würde sie überladen).
quelle
Im Wesentlichen bestimmen die Parameter der Methode, wie sich die Methode verhält.
Ein kurzes Beispiel wäre:
Wenn Sie die Methodensumme (a, b) ein paar Ganzzahlen übergeben, weiß sie, dass sie die erste Implementierung aufrufen sollte, da der Methodenaufruf mit der Methodensignatur übereinstimmt (dh die doppelte Summe (double, double) funktioniert nicht, wenn Sie die angeben Summenmethode zwei ganze Zahlen).
Die Signatur des Aufrufs muss mit den verfügbaren Implementierungen übereinstimmen. Der Versuch, sum (string, string) aufzurufen, funktioniert daher nur, wenn Sie Folgendes haben:
tl; dr: Damit die Klasse die richtige Methode gemäß den Parametern behandelt, geben Sie eine Methode mit demselben Namen an.
Beim Erben wird es als Überschreiben bezeichnet
Ein gutes Beispiel für dieses andere Szenario ist, wenn Sie das Standardverhalten einer Klasse durch Erben ändern möchten, und insbesondere, wenn Sie etwas Ähnliches wie das Muster der Vorlagenmethode haben, bei dem jeder Schritt eines Algorithmus in einer Methode implementiert ist.
Stellen Sie sich vor, Sie haben
class Robot
eine Methode namensfireAtTarget(Target target)
..., diefireWeaponA(target); fireWeaponB(target); fireWeaponC(target);
nacheinander aufruft . Sie möchten auch eine Sammlung namens robot_army haben, zu der Sie nur Objekte der Klasse Robot hinzufügen können. Roboter feuert standardmäßig Maschinengewehre in seinenfireWeaponX()
Methoden ab.Dann möchten Sie haben
class LazorRobot
undclass MissileRobot
, hast du Roboter implementieren alle immer wieder ?, nein, nur LazorRobot und MissileRobot vererben Roboter haben, und überlasten jedesfireWeaponX()
Verfahren zur Verwendung lazorz oder Raketen , und Sie werden das gleiche Verhalten mit verschiedenen Waffen haben, ohne neu zu implementieren, die der Rest der Methoden.tl; dr: Damit das Verhalten der Methode von der Klasse abhängt, ohne die Schnittstelle zu beschädigen (robot_army akzeptiert nur Robot, akzeptiert jedoch alle Klassen, die Robot erben).
quelle
when inheriting
wahrscheinlich nicht der gesamte Abschnitt benötigt wird. :)sum(String, String)
undsum(int, int)
?