Klassen & Objekte

Definition, Attribute, Methoden

Klassendefinitionen beginnen in Ruby mit dem Schlüsselwort class und enden mit dem Schlüsselwort end. In einer Klasse können Instanz- und Klassenvariablen definiert werden. Dies geschieht durch @ für Instanz- und @@ für Klassenvariablen. Analog gibt es Instanz- und Klassenmethoden. Methodendefinitionen beginnen mit def und müssen ebenfalls mit end abgeschlossen werden. Um Klassenmethoden zu kennzeichnen wird ihnen der Klassenname mit einem Punkt vorangestellt.

Methoden können, analog zu Java, als private, protected oder public gekennzeichnet werden. Per default ist eine Methode public.Attribute sind per default als private deklariert und somit außerhalb der Klasse nicht ansprechbar. Die Object-Methoden attr_reader und attr_writer (oder statt diesen beiden die Methode attr) können zur Erstellung von getter- und setter-Methoden verwendet werden.

Jede Methode in Ruby gibt ein Objekt zurück, Methoden können jedoch auch verwendet werden ohne dass man den Rückgabewert weiter verwendet. Der Rückgabewert einer Methode kann über das return-statement festgelegt werden, findet der Interpreter kein return-statement, so wird das Resultat der letzten Anweisung zurückgegeben.

Eine Instanz einer Klasse wird über die Klassenmethode new erstellt, die eventuell übergebene Parameter an die Methode initialize weitergibt.

class Klasse
  attr :size, true # true (optional) gibt an, dass auch ein setter erstellt werden soll

  def initialize (attribut)
    @attribut = attribut # Instanzvariable
    @@anzahlInstanzen += 1 # Klassenvariablen
  end

  def Klasse.wieVieleInstanzen?
    @@anzahlInstanzen # oder auch return @@anzahlInstanzen
  end

  def machEt
    puts "Mach et, Otze!"
  end

end

Object-Methoden

Es ist auch möglich, eine Methode ohne die Angabe einer Klasse zu definieren. Diese werden dann der Klasse Object zugeordnet und stehen somit global zur Verfügung:

def sagHallo
  puts "Hallo"
end

class Klasse
  def machWas
    sagHallo
  end
end


sagHallo
1.sagHallo
Klasse.new.machWas
# alle drei Aufrufe führen zum selben Ergebnis - Es wird "Hallo" ausgegeben.

Erweiterung vorhandener Klassen

Bereits existierende Klassen können in Ruby ganz einfach erweitert werden. Ist man z.B. der Meinung, eine Integer-Zahl sollte ihre Fakultät berechnen und darüber Auskunft geben können, ob sie eine Primzahl ist, kann man die Klasse wie folgt erweitern:

class Integer

  def isPrimeNr?
    x=2
    x+=1 while (x <= to_i) and (to_i % x != 0)
    x >= to_i
  end

  def fac
    if to_i == 1 then 1
    else (to_i - 1).fac * to_i end
  end

end

puts 999.isPrimeNr? # false
puts 7.isPrimeNr?   # true
puts 77.fac         # 145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000

Klassen werden in Ruby nie geschlossen, das heißt, man kann eine Klasse zur Laufzeit jederzeit ändern oder erweitern.

Vererbung & Mixins

In Ruby wird beim Anlegen neuer Klassen nur einfache Vererbung unterstützt. Dies verhindert die Komplikationen der Mehrfachvererbung, bei der es Zuordnungsprobleme für Attribute und Methoden geben kann. Um jedoch trotzdem die Vorteile der Mehrfachvererbung nutzen zu können, gibt es die Möglichkeit, das sogenannte „Mix in“-Verfahren zu nutzen. Durch die Definition von Modulen können Attribute und Methoden definiert werden, die durch die Aufnahme des Moduls in eine Klasse in dieser zur Verfügung stehen.

module Debug
  def whoAmI?
    "#{self.type.name} (\##{self.id})"
  end
end

class Klasse
  include Debug
    #...
  end
end

a = new
Klasse a.whoAmI?
# "Klasse (#537683777)"