Ich denke, dies könnte eine nützliche Sprachfunktion sein und habe mich gefragt, ob es bereits Sprachen gibt, die dies unterstützen.
Die Idee ist, wenn Sie haben:
class C
virtual F
statement1
statement2
und
class D inherits C
override F
statement1
statement2
C.F()
Auf CF () würde ein Schlüsselwort angewendet, so dass das Entfernen der letzten Codezeile zu einem Compilerfehler führen würde, da die Meldung "Diese Methode kann überschrieben werden, die Implementierung hier muss jedoch ausgeführt werden, egal was passiert" lautet.
programming-languages
Aaron Anodide
quelle
quelle
Antworten:
Ja, das tun sie. Es heißt skandinavisches Modell von OO, es wird zum Beispiel in Simula verwendet (das andere OO-Modell, das weit verbreitet ist und jetzt als selbstverständlich angenommen wird, ist ein amerikanisches Modell). Im skandinavischen Modell überschreiben Sie nicht, sondern liefern Unterverhalten.
in Superklasse Methode foo:
in Unterklasse 'Methode foo:
Wenn Sie übergeordnete Klasse nennen foo Instanzen Methode, nur
some-code-before
undsome-code-after
geschieht (INNER
tut nichts), aber wenn man Subclass nennen foo Instanzen, tut essome-code-before
,some-code-in-subclass
und dannsome-code-after
.quelle
Keine mir bekannte Sprache erzwingt das Aufrufen der überschriebenen Methode. In der Tat erlauben einige Sprachen das Überschreiben von Methoden, die nicht überschrieben werden können (z. B. die Verwendung des
new
Schlüsselworts in C #). Es gibt jedoch zwei Möglichkeiten, dies zu erreichen.Die erste Möglichkeit besteht darin, eine nicht überschreibbare Methode zu erstellen (z. B. eine, bei der das
virtual
Schlüsselwort in C # fehlt oder die dasfinal
Schlüsselwort in Java enthält), die eine überschreibbare Methode aufruft, die nicht von außerhalb der Klasse aufgerufen werden kann (z. B.protected
in C #, Java oder C ++).und
Das Überschreiben von Klassen steht
C
es frei, dasF
Verhalten zu überschreiben und zu ändern, aber Anrufer von außerhalb der Klasse greifen nur über zuA
.Bearbeiten: Wie bereits erwähnt, wird dies als Template-Methodenmuster bezeichnet .
Die zweite Möglichkeit besteht darin, eine Sprache zu verwenden, die in der Basisklasse angegebene Vor- und Nachbedingungen wie Eiffel oder C # mit Codeverträgen erzwingt. Der Aufruf der Basisklasse wird nicht erzwungen, aber die überschriebene Methode kann gezwungen werden, dieselben Anweisungen auszuführen. Die Verwendung von Aspekten kann auch hilfreich sein, wenn die Sprache die Vererbung von Aspekten ermöglicht.
quelle
private
in C ++ überschrieben wird :) Herb Sutter erklärt dies hier ausführlich.Nicht wirklich Teil der Sprache, aber der FindBugs Static Code Analyzer für Java verfügt über eine Anmerkung
OverrideMustInvoke
, die ein Entwickler zu einer Methode hinzufügen kann und die dazu führt, dass FindBugs einen Fehler anzeigt, wenn eine überschreibende Methode gefunden wird, die die Super-Implementierung nicht aufruft . Es kann sogar angegeben werden, ob der Aufruf in der überschreibenden Methode der erste oder der letzte sein muss.quelle
Das Aufrufen einer Superklasse-Methode ist ein Anti-Pattern . Wenn es zur Kompilierungszeit nicht erzwungen wird, ist es fehleranfällig. Aus diesem Grund suchen Sie nach einem Sprachkonstrukt, das es überprüft.
Es gibt einen Weg, der in allen OO-Sprachen unterstützt wird: Das Template-Methodenmuster . Hier machen Sie die Superklasse-Methode nicht überschreibbar und rufen darin eine überschreibbare Methode auf. Die Unterklasse kann dann diese Methode überschreiben, um Funktionen hinzuzufügen:
Abhängig vom Ort des Aufrufs der überschriebenen Methode kann sogar die Ausführungsreihenfolge bestimmt werden, die beim normalen Super-Aufruf vom Implementierer der Unterklasse frei gewählt wird.
quelle
Das nächste Muster, das ich mir vorstellen kann, sind selbst abonnierte Ereignisse. Es ist etwas umständlich und für den Programmierer überhaupt nicht intuitiv, erreicht aber das Ziel.
quelle
Lisp-Maschine "schmeckt" erlaubte Methoden mit dem Typ "vor" "nach" und "um" die geerbte Hauptmethode.
quelle
Theoretisch ist dies zwar keine schlechte Idee, hat aber den negativen Nebeneffekt, dass meine Optionen bei der Implementierung eingeschränkt werden
D
. Was ist zum Beispiel, wenn es (aus unerfindlichen Gründen) bequemer ist, die Superklasse-ImplementierungF
von einer anderen Methode aufzurufen :In Ihrem Szenario würde der Compiler die Implementierung von
F
inD
kennzeichnen, obwohl er (indirekt) aufruftC.F()
.Grundsätzlich ist das, was Sie beschrieben haben, ein möglicher Mechanismus, mit dem der Compiler erkennen kann, wenn ein Vertrag über Klassen, von denen erbt,
C
verletzt wird. Mein Punkt ist, dass, obwohl das eine großartige Sache ist, es nicht auf Kosten der Einschränkung gehen sollte, wie ich meine Unterklasse implementieren kann.quelle