Die Programmiersprache Ruby (German Edition)
zwischen Konstanten und Methoden ist, dass Konstanten im lexikalischen Gültigkeitsbereich des Ortes gesucht werden, in dem man sie nutzt, bevor in der Vererbungshierarchie nachgeschaut wird ( „7.9 Lookup von Konstanten“ hat die Details). Falls also
Point3D
Methoden erbt, die die Konstante
ORIGIN
nutzen, wird sich das Verhalten dieser geerbten Methoden auch dann nicht ändern, wenn
Point3D
seine eigene Version von
ORIGIN
definiert.
7.4 Erzeugen und Initialisieren von Objekten
Objekte werden in Ruby im Allgemeinen erzeugt, indem man die Methode
new
ihrer Klasse aufruft. Dieser Abschnitt erklärt, wie das genau funktioniert, und erläutert noch andere Mechanismen (wie zum Beispiel Klonen und Unmarshalling), die neue Objekte erzeugen. Jeder Unterabschnitt beschreibt, wie Sie die Initialisierung der neu erzeugten Objekte anpassen können.
7.4.1 new, allocate und initialize
Jede Klasse erbt die Klassenmethode
new
. Diese Methode hat zwei Aufgaben: Sie muss ein neues Objekt allozieren – also das Objekt zum Leben erwecken – und es initialisieren. Diese beiden Aufgaben werden dabei an die Methoden
allocate
und
initialize
delegiert. Wenn die Methode
new
selbst in Ruby geschrieben wäre, würde sie in etwa so aussehen:
def new(*args)
o = self.allocate # Erzeuge ein neues Objekt dieser Klasse
o.initialize(*args) # Rufe initialize des Objekts mit unseren Argumenten auf
o # Gib neues Objekt zurück, ignoriere Rückgabewert von initialize
end
allocate
ist eine Instanzmethode von
Class
und wird von allen Klassenobjekten geerbt. Ihr Zweck ist, eine neue Instanz der Klasse zu erzeugen. Sie können diese Methode selber aufrufen, um nicht initialisierte Instanzen einer Klasse zu erzeugen. Aber versuchen Sie nicht, sie zu überschreiben — Ruby ruft diese Methode immer direkt auf und ignoriert jede überschreibende Version, die Sie eventuell definiert haben.
----
Class::new und Class#new
Class
definiert zwei Methoden namens
new
. Die eine,
Class#new
, ist eine Instanzmethode, während es sich bei der anderen,
Class::new
, um eine Klassenmethode handelt (wir verwenden hier die eindeutigeren Namenskonventionen des ri -Tools). Die erste Methode ist die Instanzmethode, die wir beschrieben haben – sie wird von allen Klassenobjekten geerbt, wird eine Klassenmethode der Klasse und dient dazu, neue Instanzen zu erzeugen und zu initialisieren.
Die Klassenmethode
Class::new
ist die der Klasse
Class
eigene Version der Methode, die dazu genutzt werden kann, neue Klassen zu erzeugen.
----
initialize
ist eine Instanzmethode. Die meisten Klassen benötigen eine, und jede Klasse, die eine andere Klasse als
Object
erweitert, sollte
super
aufrufen, um die
initialize
-Methoden der Superklasse zu verketten. Meist ist es Aufgabe von
initialize
, Instanzvariablen für das Objekt zu erzeugen und sie auf ihre Initialwerte zu setzen. Typischerweise werden die Werte dieser Instanzvariablen aus den Argumenten ermittelt, die der Clientcode an
new
(und
new
an
initialize
übermittelt).
initialize
muss das initialisierte Objekt nicht zwingend zurückgeben. Tatsächlich wird der Rückgabewert von
initialize
ignoriert. Ruby macht die Methode
initialize
implizit privat, sie können sie also nicht explizit für ein Objekt aufrufen.
7.4.2 Fabrikmethoden
Oft ist es nützlich, Instanzen einer Klasse auf mehr als eine Weise initialisieren zu können. Das lässt sich zum Beispiel erreichen, indem Sie Parameter-Defaults für die Methode
initialize
bereitstellen. Definieren Sie
initialize
wie folgt, können Sie
new
zum Beispiel entweder mit zwei oder mit drei Argumenten aufrufen:
class Point
# Initialisieren eines Point mit zwei oder drei Koordinaten
def initialize(x, y, z=nil)
@x,@y,@z = x, y, z
end
end
Manchmal sind Parameter-Defaults allerdings nicht ausreichend, und wir müssen neben
new
noch weitere Fabrikmethoden schreiben, um Instanzen unserer Klasse zu erzeugen. Nehmen wir an, dass wir
Point
-Objekte über kartesische oder über Polarkoordinaten initialisieren:
class Point
# Definiere eine Methode initialize wie üblich
def initialize(x,y) # Erwartet kartesische Koordinaten
@x,@y = x,y
end
# Aber sorge dafür, dass die Fabrikmethode new privat ist
private_class_method :new
def Point.cartesian(x,y) # Fabrikmethode für kartesische Koordinaten
new(x,y) # Wir können new immer noch aus anderen Klassenmethoden aufrufen
end
def Point.polar(r, theta) # Fabrikmethode für Polarkoordinaten
new(r*Math.cos(theta), r*Math.sin(theta))
Weitere Kostenlose Bücher