Advanced Services | Abstrakte Klassen |
Eine abstrakte Klasse ist eine Klasse, von der man keine Objekte anlegen kann. Wozu braucht man eine
Klasse, von der man keine Objekte anlegen kann ? Das scheint auf den ersten Blick ziemlich sinnlos.
Auf den zweiten Blick jedoch durchaus nicht. Wenn man an einem Projekt arbeitet, wird man sehr
schnell zu dem Punkt kommen, wo man verschiedene Klassen entwirft, die sich aus dem gestellten Problem
ergeben. Man wird versuchen, sie in eine sinnvolle Vererbungshierarchie zu bringen und hat dann recht
bald ein halbes Dutzend oder auch mehr Klassen zusammengestellt. Man wird Methoden in verschiedenen
Klassen, die sinngemäß ähnliche Aufgaben haben, mit dem gleichen Namen versehen und dann mehr oder
weniger automatisch zu der Idee gelangen, diese Methoden weit oben in der Hierarchie anzulegen.
Die tieferliegenden Klassen werden sie dann erben und bei Bedarf überschreiben, d.h. ihren Bedürfnissen
entsprechend anpassen. Nur ein Schritt weiter ist die Idee, diese Methoden verpflichtend zu machen,
so daß man als Anwender der Klassenhierarchie einfach sicher sein kann, daß diese Methoden in allen
abgeleiteten Klassen existieren. Ähnlich kann man mit den Eigenschaften einer Klasse verfahren.
So kommt man zu der Idee, eine Klasse zu schaffen, die sozusagen für das Design der ganzen Hierarchie
zuständig ist. Von einer solchen Klasse braucht man nicht unbedingt Objekte, sie ist "nur" dafür da,
eine Klassenhierarchie konsistent zu gestalten. Aus diesem Grund hat man den Begriff der abstrakten
Klasse eingeführt. Meistens liegen abstrakte Klassen sehr weit oben in der Hierarchie.
Wie man an dem folgenden Beispiel sieht, reicht alleine der modifier abstract aus, um eine Klasse abstrakt
zu machen. Obwohl der Konstruktor public ist kann man nun von dieser Klasse keine Objekte mehr anlegen.
// ------------------------ Klasse Abstract ------------------------ \\ public abstract class Abstract { int a ; public Abstract() // Konstruktor { } public void NichtAbstract() // "normale" Methode { } } // ---------------------- Klasse AbstractDemo ---------------------- \\ class AbstractDemo { static void Main(string[] args) { Abstract abs; // das geht //abs = new Abstract(); // das geht nicht // compiletime error: // Cannot create an instance of the abstract class or interface } }
Im obigen Fall verbietet der Entwickler explizit das instantiieren von Objekten dieser Klasse. Würde er das Wort abstract weglassen, so könnte man von dieser Klasse problemlos Objekte anlegen.
Häufiger ist der Fall, daß man eine Klasse abstrakt machen muß. Neben dem Begriff der abstrakten Klasse gibt es nämlich auch noch den Begriff der abstrakten Methode. Eine abstrakte Methode ist eine Methode ohne Rumpf, also ohne Implementierung. Das folgende Beispiel enthält eine abstrakte und eine nicht abstrakte Methode.
public class Abstract2 // hier fehlt der modifier abstract { public void NichtAbstract() { } public abstract void SchonAbstract(); // Semikolon nicht vergessen !! // SchonAbstract() is abstract but it is contained in a non-abstract class }
Enthält eine Klasse (mindestens) eine abstrakte Methode, dann muß auch die Klasse abstract sein. Leitet man eine Klasse ab, die abstrakte Methoden enthält, dann ist die abgeleitete Klasse selbst wieder abstrakt. Sie kann allerdings real werden, wenn man (sämtliche) geerbten abstrakten Methoden implementiert. Leitet man dagegen von einer abstrakten Klasse ab, die keine abstrakten Methoden enthält, dann ist diese Ableitung automatisch real. Die letzte Situation ist nicht so abwegig, wie man vermuten möchte, sie kommt durchaus in der Praxis vor. Hier nochmal das obige Beispiel, aber diesmal ohne Fehler:
public abstract class Abstract2 // OK { public void NichtAbstract() { } public abstract void SchonAbstract() ; // Semikolon nicht vergessen !! }
Noch etwas müssen wir uns merken: Eine abstrakte Methode kann weder statisch noch private sein.
Hier eine kleine Zusammenfassung.
Die vorletze Einschränkung leuchtet nach kurzem Nachdenken unmittelbar ein. Überlegen Sie mal.
Eine weitere Anwendung von abstrakten Klassen sind Klassen, die sozusagen schon fast fertig sind.
Gemeint damit ist, daß die abstrakte Klasse fast alle Methoden, die für einen bestimmten Zweck
notwendig sind, schon implementiert und lediglich ein oder zwei abstrakte Methoden übrigläßt.
Man verwendet solche Klassen derart, daß man von Ihnen eine Ableitung bildet und die abstrakten
Methoden nach seinen Bedürfnissen implementiert.
public abstract class Abstract2 { public void NichtAbstract() { } public abstract void SchonAbstract(); // Semikolon nicht vergessen !! // SchonAbstract() is abstract but it is contained in non-abstract class protected abstract void SchonAbstract2(); // Semikolon nicht vergessen !! internal abstract void SchonAbstract3(); // Semikolon nicht vergessen !! //public static abstract void SchonAbstract4(); // A static member cannot be marked as override, virtual, or abstract // virtual or abstract members cannot be private }
class DerivedFromAbstract2 : Abstract2
{
override public void SchonAbstract() // override notwendig !!
{
}
override protected void SchonAbstract2() // override notwendig !!
{
}
override internal void SchonAbstract3() // override notwendig !!
{
}
//cannot change access modifiers when overriding inherited member
}
Im obigen Beispiel implementiert die Klasse DerivedFromAbstract2 alle abstrakten Methoden aus Abstract2. Dabei ist darauf zu achten, daß bei der Implementierung die Zugriffsmodifizierer genau übernommen werden müssen (siehe roter Kommentar),
Neben Methoden können auch Properties abstrakt sein. Properties werden ja vom Compiler im Hintergrund als Methoden implementiert. Das folgende Beispiel zeigt die Deklaration einer abstrakten Property FileSize.
public abstract class Abstract3 { public abstract long FileSize { get; set; } }
Das ist nicht zu verwechseln mit automatisch implementierten Properties. Die Syntax hierfür sieht abstract aus, ist es aber nicht!
public class Person { // auto-implemented properties public string Vorname { get; set; } public string Nachname { get; set; } //.. }
Die Implementierung einer abstrakten Property sieht wie folgt aus.
class DerivedFromAbstract3 : Abstract3 { private long fileSize; override public long FileSize { get { return fileSize; } set { fileSize = value; } } }
Abstrakte Properties können nicht automatisch implementiert werdem, es gibt dafür in C# keine Syntax.
1) Bestätigen Sie durch ein geeignetes Beispiel, daß eine abstrakte Methode immer virtuell ist.
2) Die abstrakte Klasse AbsPers