Aus Neugierde habe ich versucht, eine abstrakte Methode in der Basisklasse zu überschreiben, und die Implementierungszusammenfassung. Wie nachstehend:
public abstract class FirstAbstract
{
public abstract void SomeMethod();
}
public abstract class SecondAbstract : FirstAbstract
{
public abstract override void SomeMethod();
//?? what sense does this make? no implementaion would anyway force the derived classes to implement abstract method?
}
Neugierig zu wissen, warum der C # -Compiler das Schreiben von 'abstract override' zulässt. Ist es nicht überflüssig? Sollte ein Fehler beim Kompilieren sein, um so etwas zu tun. Dient es zu einem Anwendungsfall?
Danke für Ihr Interesse.
Es gibt ein nützliches Beispiel dafür auf MSDN - grundsätzlich können Sie eine abgeleitete Klasse zwingen, eine neue Implementierung für eine Methode bereitzustellen.
public class D
{
public virtual void DoWork(int i)
{
// Original implementation.
}
}
public abstract class E : D
{
public abstract override void DoWork(int i);
}
public class F : E
{
public override void DoWork(int i)
{
// New implementation.
}
}
Wenn eine virtuelle Methode als abstrakt deklariert wird, ist sie für ein beliebiges .__ noch virtuell. Klasse, die von der abstrakten Klasse erbt. Eine Klasse, die ein .__ erbt. Die abstrakte Methode kann nicht auf die ursprüngliche Implementierung von .__ zugreifen. method - Im vorherigen Beispiel kann DoWork der Klasse F DoWork nicht aufrufen auf Klasse D. Auf diese Weise kann eine abstrakte Klasse abgeleitete Klassen erzwingen um neue Methodenimplementierungen für virtuelle Methoden bereitzustellen.
Ich finde es sehr nützlich, um die korrekte Implementierung von ToString()
in abgeleiteten Klassen sicherzustellen. Nehmen wir an, Sie haben eine abstrakte Basisklasse und möchten, dass alle abgeleiteten Klassen eine bedeutende ToString()
-Implementierung definieren, da Sie sie aktiv verwenden. Mit abstract override
geht das sehr elegant:
public abstract class Base
{
public abstract override string ToString();
}
Es ist ein klares Signal an die Implementierer, dass ToString()
in der Basisklasse verwendet wird (wie das Schreiben der Ausgabe an den Benutzer). Normalerweise würden sie nicht darüber nachdenken, diese Überschreibung zu definieren.
Interessanterweise enthält die Roslyn-Version des C # -Compilers eine abstrakte Überschreibungsmethode, die ich seltsam genug fand, um einen Artikel zu schreiben:
Stellen Sie sich vor, dass SecondAbstract
sich in der Mitte einer Drei-Klassen-Hierarchie befindet, und er möchte einige abstrakte Methoden von seiner Basis FirstAbstract
aus implementieren, während er eine andere Methode X aus seinem untergeordneten ThirdAbstract
verwendet.
In diesem Fall muss SecondAbstract
die Methode X mit abstract
schmücken, da sie keine Implementierung bereitstellen möchte. Gleichzeitig muss es mit override
verziert werden, da es keine neue Methode X definiert, sondern die Verantwortung für die Implementierung von X auf das untergeordnete Element verlagert werden soll. Daher abstract override
.
Im Allgemeinen sind die durch abstract
und override
modellierten Konzepte orthogonal. Die erste erzwingt abgeleitete Klassen, eine Methode zu implementieren, während die zweite erkennt, dass eine Methode dieselbe ist wie in einer Basisklasse angegeben und keine new
-Methode.
Deshalb:
abstract
: abgeleitete Klasse muss implementierenoverride
: Implementierung der in der Basisklasse definierten Methodeabstract override
: Die abgeleitete Klasse muss eine in der Basisklasse definierte Methode implementierenWenn Sie SomeMethod
nicht als abstract override
in SecondAbstract
deklariert haben, würde der Compiler erwarten, dass diese Klasse eine Implementierung der Methode enthält. Mit abstract override
ist klar, dass die Implementierung in einer von SecondAbstract
abgeleiteten Klasse und nicht in SecondAbstract
selbst sein sollte.
Hoffe das hilft...
Dieses Entwurfsmuster wird als Vorlagenmethode bezeichnet.
Wikipedia-Seite zu Vorlagenmethoden
Ein einfaches Nicht-Software-Beispiel: Es gibt eine Menge militärischer Einheiten: Panzer, Jets, Soldaten, Schlachtschiffe usw. Sie alle müssen einige gängige Methoden implementieren, die sie jedoch sehr unterschiedlich implementieren:
usw...
Dies geschieht, da Sie in der Kindklasse keine abstract
-Methode mit demselben Namen wie in der Basisklasse haben können. override
teilt dem Compiler mit, dass Sie das Verhalten der Basisklasse überschreiben.
Hoffe, das ist es, wonach du suchst.