2010-03-18 15 views
5

ich über Design Patterns und in den Beispielen von Code zu lernen Ich habe eine Konvention gesehen, wo die abstrakte Klasse eine Methode, zum Beispiel erklärt:abstrakte Methode Unterschrift, Vererbung und „Do“ Namenskonvention

public abstract class ServiceBase { 
... 

public virtual object GetSomething(); 

und dann

protected abstract object DoGetSomething(); 

Meine Frage ist, warum diese beiden Methoden existieren, da sie den gleichen Zweck zu dienen scheinen. Ist dies so, dass die Methodenlogik der Basisklasse GetSomething() nicht durch geerbte Klassen überschrieben werden kann? Aber andererseits ist die Methode virtuell markiert, so dass sie trotzdem überschrieben werden kann. Was nützt es hier, Implementierer von abgeleiteten Klassen zu benötigen, um die abstrakte Methode zu implementieren, wenn die virtuelle Methode trotzdem aufgerufen werden kann?

+0

Soll GetSomething virtuell sein? – JaredPar

+0

Ja, es ist definitiv virtuell. –

Antwort

4

Ein häufiger Grund besteht darin, die abstrakte Methode mit Standardhandling zu behandeln. Zum Beispiel kann die abstrakte Methode möglicherweise nur unter bestimmten Umständen aufgerufen werden - beispielsweise nachdem die Splines vernetzt wurden. In diesem Fall ist es sinnvoll, _areSplinesReticulated an einer Stelle zu überprüfen - die öffentliche GetSomething-Methode -, anstatt jede Implementierung der abstrakten Methode zur Durchführung einer eigenen Überprüfung zu benötigen. Oder vielleicht GetSomething ist 90% Boilerplate, erfordert aber ein wenig zusätzliche Logik oder eine entscheidende Information, die nur abgeleitete Klassen liefern können.

Dies ist eine Form der Template Method Muster.

Ein nicht virtuelles GetSomething bedeutet, dass jede abgeleitete Klasse die Standardbehandlung erhält und nur über ihre benutzerdefinierte Version von DoGetSomething teilnehmen kann. Wenn GetSomething virtuell ist, können abgeleitete Klassen die Standardbehandlung umgehen, wenn sie möchten. Beides ist eine praktikable Strategie, die davon abhängt, ob die standardmäßige GetSomething-Behandlung integraler Bestandteil der Klassenlogik ist (z. B. Invarianten) oder ob die Basisklasse den abgeleiteten Klassen maximale Flexibilität gewähren will.

0

ich nicht die Version, die Sie beschreiben, gesehen habe, wo „GetSomething()“ ist virtuell, aber ich habe gesehen (und geschrieben) Klassen wie folgt aus:

public abstract class Foo 
{ 
    protected abstract void DoBar(); 

    public void Bar() 
    { 
     // do stuff that has to happen regardless of how 
     // DoBar() has been implemented in the derived 
     // class 
     DoBar(); 
     // do other stuff 
    } 
} 

Da „Bar“ ist nicht virtuell (Und ich nehme an, Sie könnten es auch versiegeln, nur um sicherzugehen) Sie haben die Möglichkeit, Code vor und nach dem Aufruf der "DoBar" -Methode zu "injizieren". Es ist ziemlich praktisch.

Verwandte Themen