Die Programmiersprache Ruby (German Edition)
Klasse keine Superklasse angeben, erweitert Ihre Klasse implizit
Object
. Eine Klasse kann eine beliebige Anzahl von Subklassen besitzen, und jede Klasse hat eine einzelne Superklasse – außer
Object
, das keine Superklasse besitzt.
Die Tatsache, dass Klassen viele Subklassen, aber nur eine Superklasse besitzen können, bedeutet, dass sie sich in einer Baumstruktur anordnen lassen, die wir als Klassenhierarchie von Ruby bezeichnen. Die Klasse
Object
ist die Wurzel dieser Hierarchie, und jede Klasse erbt direkt oder indirekt von ihr. Die Nachkommen einer Klasse sind die Subklassen der Klasse sowie die Subklassen der Subklassen und so weiter. Die Vorfahren einer Klasse sind die Superklasse, die Superklasse der Superklasse und so weiter bis hoch zu
Object
. Abbildung 5.5 in Kapitel 5 zeigt den Teil der Klassenhierarchie von Ruby, der
Exception
und ihre Nachkommen enthält. In dieser Abbildung können Sie sehen, dass die Vorfahren von
EOFError
die Klassen
IOError
,
StandardError
,
Exception
und
Object
sind.
----
BasicObject in Ruby 1.9
In Ruby 1.9 ist
Object
nicht mehr die Wurzel der Klassenhierarchie. Eine neue Klasse namens
BasicObject
steht nun an ihrer Stelle, und
Object
ist eine Subklasse von
BasicObject
.
BasicObject
ist eine sehr einfache Klasse, die so gut wie keine eigenen Methoden enthält. Sie kann als Superklasse von Delegating-Wrapper-Klassen dienen (wie die in Listing 8.5 in Kapitel 8 ).
Wenn Sie in Ruby 1.9 eine Klasse erstellen, erweitern Sie immer noch
Object
, sofern Sie nicht explizit die Superklasse angeben. Die meisten Programmierer werden niemals
BasicObject
verwenden oder erweitern.
----
Die Syntax zum Erweitern einer Klasse ist einfach. Fügen Sie Ihrer
class
-Anweisung das Kleiner-Zeichen
<
und den Namen der Superklasse hinzu, zum Beispiel:
class Point3D < Point # Definiere Klasse Point3D als Subklasse von Point
end
Wir werden diese dreidimensionale
Point
-Klasse in den folgenden Unterabschnitten mit Leben füllen und zeigen, wie Methoden von der Superklasse geerbt werden und wie man die geerbten Methoden überschreiben oder erweitern kann, um der Subklasse neue Verhaltensweisen zu ermöglichen.
----
Eine Subklasse von einer Struct bilden
Weiter oben in diesem Kapitel haben Sie gesehen, wie man mit
Struct.new
automatisch einfache Klassen erzeugen kann. Es ist auch möglich, eine Subklasse einer Struct-basierten Klasse zu bilden, in der man dann nicht automatisch generierte Methoden hinzufügen kann:
class Point3D < Struct.new("Point3D", :x, :y, :z)
# Superklasse struct gibt uns Akzessormethoden, ==, to_s usw.
# Punktspezifische Methoden hier einfügen
end
----
7.3.1 Methoden erben
Die Klasse
Point3D
, die wir definiert haben, ist eine triviale Subklasse von
Point
. Sie deklariert sich selbst als Erweiterung von
Point
, aber es gibt keinen Klassenrumpf, daher wird dieser Klasse nichts hinzugefügt. Ein Objekt vom Typ
Point3D
ist im Endeffekt das Gleiche wie ein
Point
-Objekt. Einer der wenigen sichtbaren Unterschiede ist der Wert, der von der Methode
class
zurückgegeben wird:
p2 = Point.new(1,2)
p3 = Point3D.new(1,2)
print p2.to_s, p2.class # Ausgabe: "(1,2)Point"
print p3.to_s, p3.class # Ausgabe: "(1,2)Point3D"
Der von der Methode
class
zurückgegebene Wert ist anders. Wichtiger an diesem Beispiel aber ist, was gleich bleibt. Unser Objekt
Point3D
hat die Methode
to_s
geerbt, die von
Point
definiert wurde. Auch wurde die Methode
initialize
geerbt — wodurch wir ein
Point3D
-Objekt mit dem gleichen Aufruf von
new
erzeugen können, den wir auch für ein
Point
-Objekt genutzt haben. [ 27 ] Es gibt ein weiteres Beispiel für Methodenvererbung in diesem Code: Sowohl
Point
als auch
Point3D
erben die Methode
class
von
Object
.
7.3.2 Methoden überschreiben
Wenn wir eine neue Klasse definieren, fügen wir ihr neues Verhalten durch die Definition neuer Methoden hinzu. Genauso wichtig kann es aber sein, das vererbte Verhalten der Klasse anzupassen, indem wir vererbte Methoden überschreiben.
So definiert zum Beispiel die Klasse
Object
eine (ziemlich generische) Methode
to_s
zum Umwandeln eines Objekts in einen String:
o = Object.new
puts o.to_s # Gibt in etwa so etwas aus: "#"
Wenn wir eine Methode
to_s
in der Klasse
Point
definieren, überschreiben wir die von
Object
geerbte Methode
to_s
.
Ein wichtiges Element bei objektorientierter Programmierung und dem Erstellen von Subklassen ist, dass aufgerufene Methoden dynamisch nachgeschlagen werden, so dass die
Weitere Kostenlose Bücher