Die Programmiersprache Ruby (German Edition)
zwei Zahlen initialisieren, die ihre x - und y -Koordinaten repräsentieren. In vielen objektorientierten Sprachen geschieht dies durch einen »Konstruktor«. In Ruby nutzen wir dafür die Methode
initialize
:
class Point
def initialize(x,y)
@x, @y = x, y
end
end
Das sind nur drei zusätzliche Zeilen Code, aber es gibt eine Reihe von Dingen, auf die wir hier hinweisen wollen. Wir haben das Schlüsselwort
def
schon ausführlich in Kapitel 6 erläutert. Aber das Kapitel konzentrierte sich auf das Definieren globaler Funktionen, die überall genutzt werden können. Wird
def
hingegen so wie hier mit einem nicht qualifizierten Methodennamen innerhalb einer
class
-Definition verwendet, legt man damit eine Instanzmethode für die Klasse fest. Eine Instanzmethode ist eine Methode, die für die Instanz einer Klasse aufgerufen wird. Bei einem solchen Aufruf enthält
self
eine Instanz der Klasse, in der die Methode definiert ist.
Der nächste wichtige Punkt ist, dass die Methode
initialize
in Ruby eine besondere Bedeutung hat. Die Methode
new
des Klassenobjekts erzeugt ein neues Instanzobjekt, für das dann automatisch die Methode
initialize
dieser Instanz aufgerufen wird. Alle Argumente, die Sie
new
mitgeben, werden an
initialize
weitergereicht. Da unsere Methode
initialize
zwei Argumente erwartet, müssen wir nun auch beim Aufruf von
Point.new
zwei Werte mitgeben:
p = Point.new(0,0)
Neben der Tatsache, dass die Methode
initialize
automatisch von
Point.new
aufgerufen wird, ist sie auch automatisch privat. Ein Objekt kann sein
initialize
selber aufrufen, aber sie können es nicht explizit für
p
aufrufen, um seinen Zustand zurückzusetzen.
Nun wollen wir uns den Rumpf der Methode
initialize
anschauen. Dort werden die beiden Werte, die wir übergeben haben und die sich in den lokalen Variablen
x
und
y
befinden, genommen, und den beiden Instanzvariablen
@x
und
@y
zugewiesen. Instanzvariablen beginnen immer mit
@
und »gehören« immer dem Objekt, auf das
self
verweist. Jede Instanz unserer Klasse
Point
besitzt ihre eigene Kopie dieser beiden Variablen, die die jeweiligen x - und y -Koordinaten enthalten.
----
Kapselung von Instanzvariablen
Die Instanzvariablen eines Objekts können nur von den Instanzmethoden dieses Objekts angesprochen werden. Code, der sich nicht innerhalb einer Instanzmethode befindet, kann die Werte einer Instanzvariablen nicht lesen oder schreiben (solange er nicht eine der reflektiven Techniken nutzt, die in Kapitel 8 beschrieben sind).
----
Schließlich noch eine Warnung an Programmierer, die mit Java oder ähnlichen Sprachen vertraut sind: In statisch typisierten Sprachen müssen Sie Ihre Variablen deklarieren, auch die Instanzvariablen. Sie wissen, dass Variablen in Ruby nicht deklariert werden müssen, aber Sie haben vielleicht trotzdem das Bedürfnis, etwas wie das Folgende zu schreiben:
# Falscher Code!
class Point
@x = 0 # Erzeugen einer Instanzvariablen @x und Zuweisen eines Standardwerts. FALSCH!
@y = 0 # Erzeugen einer Instanzvariablen @y und Zuweisen eines Standardwerts. FALSCH!
def initialize(x,y)
@x, @y = x, y # Nun Initialisieren der vorher erzeugten @x und @y.
end
end
Dieser Code macht nicht all das, was ein Java-Programmierer erwarten würde. Instanzvariablen werden immer im Kontext von
self
aufgelöst. Wenn die Methode
initialize
aufgerufen wird, enthält
self
eine Instanz der Klasse
Point
. Aber der Code außerhalb dieser Methode wird als Teil der Definition der Klasse
Point
ausgeführt. Wenn diese ersten beiden Zuweisungen umgesetzt werden, bezieht sich
self
auf die Klasse
Point
selbst, nicht auf eine Instanz der Klasse. Die Variablen
@x
und
@y
innerhalb der Methode
initialize
sind ganz andere als die außerhalb der Methode.
7.1.4 Definieren einer Methode to_s
So gut wie jede Klasse, die Sie definieren, sollte eine Instanzmethode
to_s
besitzen, um eine String-Darstellung des Objekts zurückgeben zu können. Diese Fähigkeit ist insbesondere beim Debuggen unbezahlbar. So könnte die Methode für
Point
aussehen:
class Point
def initialize(x,y)
@x, @y = x, y
end
def to_s # Gib einen String zurück, der diesen Punkt darstellt
"(#@x,#@y)" # Einfach die Instanzvariablen in einem String zusammenfassen
end
end
Mit dieser neuen Methode können wir Punkte erzeugen und ausgeben:
p = new Point(1,2) # Erzeugen eines neuen Point-Objekts
puts p # Gibt "(1,2)" aus
7.1.5 Akzessoren und Attribute
Unsere Klasse
Point
nutzt zwei Instanzvariablen. Wie wir allerdings bemerkt haben,
Weitere Kostenlose Bücher