9.5 Generics und Vererbung
Generische Klassen können abgeleitet werden. Die Regeln sind ähnlich denen, die wir schon kennen. Aufgrund der besonderen Natur generischer Klassen sind dabei jedoch ein paar Besonderheiten zu beachten.
Ist die Basisklasse generisch, kann die abgeleitete Klasse den generischen Typparameter übernehmen und selbst generisch sein.
class BaseClass<T> { [...] }
class SubClass<T> : BaseClass<T> { [...] }
Die Basisklasse könnte die konkreten Datentypen durch einen Constraint auf ganz bestimmte Typen eingrenzen. Dieser Constraint gilt auch für die abgeleitete Klasse und muss hinter der Angabe der Basisklasse berücksichtigt werden.
class BaseClass<T> where T : IComparable {
[...]
}
class SubClass<T> : BaseClass<T> where T : IComparable {
[...]
}
Soll die abgeleitete Klasse nicht generisch sein, muss der generische Typparameter der Basisklasse durch einen konkreten Datentyp in der abgeleiteten Klasse ersetzt werden, wie nachfolgend gezeigt wird:
class BaseClass<T> {
[...]
}
class SubClass : BaseClass<int> {
[...]
}
Sie können umgekehrt auch dann eine generische Subklasse entwickeln, wenn die Basisklasse nicht generisch ist.
9.5.1 Virtuelle generische Methoden
Sind in der Basisklasse virtuelle Methoden definiert, wird es noch einmal spannend, denn die Methode könnte in der Basisklasse einen generischen Typparameter haben. Virtuelle Methoden können mit override überschrieben werden. Ob der generische Typparameter durch einen konkreten Datentyp ersetzt werden muss oder ob der Typparameter auch in der überschreibenden Methode angeführt werden darf, entscheidet sich schon bei der Festlegung der Subklasse.
Spielen wir den Fall durch, dass die ableitende Klasse den geerbten generischen Typparameter konkret ersetzt, also:
class BaseClass<T> {
public virtual T DoSomething() { [...] }
}
class SubClass : BaseClass<int> {
public override int DoSomething() { [...] }
}
Wie weiter oben beschrieben wurde, muss der Typparameter durch eine konkrete Angabe ersetzt werden. Das verpflichtet auch dazu, den gewünschten Datentyp in der Signatur der überschreibenden Methode zu benennen. Dass sich die Methode polymorph verhalten wird, bedarf kaum noch einer Erwähnung.
Soll auch die abgeleitete Klasse generisch sein, muss die virtuelle Methode mit generischen Typparametern überschrieben werden.
class BaseClass<T> {
public virtual T DoSomething() { [...] }
}
class SubClass<T> : BaseClass<T> {
public override T DoSomething() { [...] }
}
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.