2013-04-19 8 views

Antwort

17

Das gebräuchlichste Verhalten ist der Aufruf inherited. Wenn ich also das vererbte Verhalten nicht explizit möchte, rufe ich nicht inherited. Ansonsten tue ich es. Wenn das geerbte Verhalten ein No-Op wie TObject.Create/Destroy ist, rufe ich immer noch inherited.

Beachten Sie auch, dass die Situtation für Konstruktoren und Destruktoren vielleicht etwas anders ist als bei anderen Methoden. Es ist äußerst selten, dass Sie einen Aufruf der geerbten Methode überspringen müssen. Ich kann mir kein Beispiel vorstellen. Konstrukteure erstellen und zerstören immer wieder andere Objekte. Wie können Sie das überspringen?

Ich weiß, dass einige Autoren Code schreiben, der inherited bei direkter Ableitung von TObject wegläßt, weil sie wissen, dass die Implementierung in TObject nichts tut. Ich mag das nicht und für mich ist es ein Fehler, das zu tun. Die Implementierungsdetails von TObject sollten nicht in abgeleitete Klassen eindringen.

Ich bin mir ziemlich sicher, dass TObject.Create/Destroy immer No-Ops sein wird. Wenn Embarcadero das geändert hat, dann würde so viel Code kaputt gehen. Aber was ist mit einem deiner Klassen? Angenommen, Sie haben eine Klasse, die von TObject abgeleitet ist. Und dann haben Sie eine andere Klasse von dem abgeleitet:

TMyClass1 = class 
    .... 
end; 

TMyClass2 = class(TMyClass) 
    .... 
end; 

Sie haben keinen Konstruktor für TMyClass1 und einen Konstruktor für TMyClass2 die wie folgt aussieht:

constructor TMyClass2.Create; 
begin 
    // no need to call inherited, it's a no-op 
    FMyObj := TBlahBlah.Create; 
end; 

Dann einen Tag den TMyClass1 Konstruktor ändern zu tun etwas. Jetzt ist TClass2 defekt. Also würde ich nie einen Anruf an inherited weglassen, weil dieser Anruf nichts tut.

Die Situation für normale Instanzmethoden ist ein wenig anders. Es ist plausibler, dass Sie die Basisklassenimplementierung ignorieren und eine brandneue Implementierung bereitstellen möchten. Aber treffen Sie die Entscheidung, basierend darauf, was die abgeleitete Klasse tun möchte, und nicht, ob die Superklasse eine leere Implementierung für die Methode hat oder nicht.

+0

+1 für den Teil "Implementierungsdetails". Tatsächlich könnten einige zukünftige Versionen von RTL entscheiden, tatsächlich wichtigen Code in diese leeren Methoden zu schreiben. –

4

Sie müssen nur inherited aufrufen, wenn Sie möchten, dass der Code der Vorfahren ausgeführt wird. Manchmal brauchen Sie diesen Code, manchmal nicht. Sie können auch Conditionals verwenden und inherited nur aufrufen, wenn eine Bedingung erfüllt ist, und Sie können wählen, wenn dies tun soll (Methodenanfang, Methodenende, ...).

Daher hängt alles von der Situation ab.

Here's ein Beispiel.

+0

Ich persönlich mache es am Ende, vor allem, wenn ich von TThread absteige. –

+5

Sie tun es am Ende, wenn es das Richtige ist, zum Beispiel in einem Destruktor. Und am Anfang, wenn das zum Beispiel in einem Konstruktor richtig ist. Und Sie können es auch in der Mitte der Methode für bestimmte Instanzmethoden tun. Wenn Sie von "TThread" abstammen, müssen Sie den geerbten Konstruktor nicht als letzte Aktion in Ihrem Konstruktor aufrufen. Ich denke, Sie denken fälschlicherweise, dass der geerbte Konstruktor beginnt, den Thread auszuführen. Es tut nicht. Das passiert in 'AfterConstruction'. –

0

Auch wenn TObject Create/Destroy Methoden nichts in der aktuellen Version tun, könnten sie in einer zukünftigen Version (unwahrscheinlich, aber immer noch). Ist es jetzt ein MUSS für dich?Nein, weil es nichts bewirkt, sondern nur, weil das aktuelle Elternelement keine Funktionalität hinzufügt.

Wenn Sie möchten, dass Ihre Nachkommenobjekte ihren Eltern immer Funktionen hinzufügen, wäre es wahrscheinlich eine gute Idee, inherited einheitlich aufzurufen.

Verwandte Themen