Als Vererbung im Sinne der Informatik bezeichnet man den Effekt, dass ein oder mehrere Superklassen (auch Elternklassen) ihre Eigenschaften und/oder Methoden an ihre Subklassen (auch Kindklassen) weitergeben. In Ruby hat jede Klasse - anders als in vielen anderen Programmiersprachen - genau eine direkte[1] Superklasse. Von dieser Superklasse erbt eine Subklasse alle Methoden und benutzt sie, als wären sie ihre eigenen.
EinfachvererbungDies ist reguläre Art der Vererbung und ist recht einfach aufgebaut. Zunächst einmal benötigt man eine Elternklasse, die alle ihre Methoden an eine Kindklasse weitervererben wird. Dann erstellt man diese Kindklasse und gibt bei der Klassendefinition zusätzlich an, von welcher Klasse sie erbt:
Um dem Konzept des Duck Typing gerecht zu werden, sollte man diese Methode aber nicht dazu benutzen, sicherzustellen, dass man z.B. einen String erhalten hat. Möchte man wirklich irgendeine Gewissheit haben (was dennoch zumeist unnötig ist), kann man die Methode Object#respond_to? verwenden, die prüft, ob eine bestimmte Methode zur Verfügung steht.
Mehrfachvererbung: MixinsWie schon weiter oben beschrieben, nutzt Ruby standardmäßig Einfachvererbung. Das heißt aber nicht, dass Mehrfachvererbung unmöglich wäre; es ist nur so, dass Ruby in dieser Hinsicht ein auf den ersten Blick zwar ungewöhnliches, aber auf den Zweiten nichtsdestotrotz praktisches System nutzt: Mixins. Ein Mixin ist prinzipiell einfach ein Modul, in dem jedoch keine Modulmethoden definiert wurden, sondern Instanzmethoden. Bestimmt ist jeder von euch schon einmal in diesen Fehler gelaufen:
Das Problem ist hier offensichtlich, dass bar keine Modulmethode von Foo ist, sondern eine Instanzmethode. Dies führt uns nun zur Mehrfachvererbung: Denn Mixins sind der einzige Weg, um "Instanzmethoden von Modulen" nutzen zu können. Der Begriff "Mixin" heißt soviel wie "Einmischen" und genau das tut man mit einem Mixin auch: Man mischt es mithilfe der Methode #include in eine Klasse ein.
Bekannte MixinsEs gibt zwei besonders bekannte Mixins: Enumerable und Comparable. Enumerable wird dazu genutzt, um eine Datenstruktur iterierbar zu machen; es setzt lediglich das Vorhandensein einer each-Methode voraus.
Ausgabe:
Comparable ermöglicht Vergleiche, setzt aber das Vorhandensein der Methode <=> voraus, welche -1 für kleiner, 0 für gleich und +1 für größer zurückgeben muss. Auf dieser Basis definiert es dann die Methoden <, <=, ==, >=, > und between?.
VerwandtschaftZusätzlich zu diesen direkten Möglichkeiten der Vererbung gibt es noch eine weitere, die aber im Grunde nur ein Sonderfall der Einfachvererbung ist. In Ruby stammt jedes Objekt, sofern nicht anders angegeben, direkt von der Klasse Object ab (ab 1.9 von BasicObject). Dadurch wird sichergestellt, dass wichtige Methoden wie equal?, das eine Gleichheitsprüfung auf der Objekt-ID durchführt, implementiert werden. Dementsprechend gilt für jedes Objekt:
Fußnoten[1]Implizit kann eine Klasse natürlich mehrere Superklassen haben, indem sie die Subklasse von X, was die Subklasse von Y, was wiederum die Subklasse von ..., ist.
Siehe auch |
|||||||||||||||||||||||||||||||||