Ruby-Programmierung: Objektorientierung
Aus Wikibooks
Zurück zu Ruby-Programmierung Hauptmenü
[Bearbeiten] Klassen
Klassen sind in erster Linie wie in jeder objektorientierten Sprache Container für Daten mit Methoden. Variablen mit Gültigkeit für die Lebensdauer der Klasseninstanz (des Objekts) werden mit voranstehendem @ geschrieben und heissen Instanzvariablen.
Der Konstruktor ist eine ganz normale Instanzmethode und hört auf den Namen initialize:
class Drink def initialize(name) @name = name end def drink puts "Drinking #{@name}" end end
Nun kann von der Klasse Drink ein Objekt erzeugt werden:
d = Drink.new('Juice')
Die Instanzvariable @name ist nun ein String "Juice". Auf das Objekt d, die Instanz, kann nun die Methode drink aufgerufen werden:
d.drink
Das erzeugt folgende Ausgabe:
Drinking Juice
[Bearbeiten] Vererbung
In einer objektorientierten Sprache ist natürlich auch Vererbung vorhanden:
class Mate < Drink def initialize super "Club Mate" end end
Die Klasse Mate erbt die Eigenschaften und Methoden der Klasse Drink. Dafür hat sie einen parameterlosen Konstruktor, welcher mit dem Schlüsselwort super dieselbe Methode in der Elternklasse (den Konstruktor von Drink) mit einem Parameter aufruft.
Wir können nun ebenfalls eine Instanz von Mate erstellen:
m = Mate.new m.drink
Dies erzeugt folgende Ausgabe:
Drinking Club Mate
[Bearbeiten] Design Pattern
Visitor Pattern Beipiel Flugzeug
class Flugzeug attr_accessor :arr def initialize() @arr=Array.new() end #def initialize def ausgabe(v) @arr.each do |ele| ele.accept(v) end #do end #def ausgabe def push(o) @arr.push(o) end #def push end #class Flugzeug
Mögliche Speicherung von Objekten im der Flugzeug-Klasse
class Person include Visitor_conect attr_accessor :name, :age, :gender, :weight, :task def initialize(name,age,agender,weight,task) @name = name @age = age @gender=gender @weight=weight @task=task end end #class Person
class Ladung include Visitor_conect attr_accessor :ort, :weight, :content def initialize(ort,weight,content) @ort = ort @weight=weight @content=content end end #class Ladung
nun zur Anbindung des Visitorcode mit Hilfe einen Modul in allen Klasse die im Flugzeug vorkommen können
module Visitor_conect def accept(v) v.visit(self) end #def accept(v) end #module Visitor_conect
Erstellen einer Visitor Klasse Ausgabe aller Menschen im Flugzeug
class Visitor_Personen def visit(o) case o.class.to_s when "Person" p "Namen #{o.name}" when "Ladung" end #case end #def visit end #class Visitor
Ausgabe mit Beispiel
p1=Person.new("Micky Mouse",60,"male",80,"Pilot") p2=Person.new("Donald Duck",60,"male",81,"Passenger") l1=Ladung.new("Container",60,"Inhalt") l2=Ladung.new("Container",40,"Inhalt") l3=Ladung.new("Container",50,"Inhalt") f=Flugzeug.new f.push(p1) f.push(p2) f.push(l1) f.push(l2) f.push(l3) f.ausgabe(Visitor_Personen.new)
Ausgabe
"Namen Micky Mouse" "Namen Donald Duck"
mit einer andern Visitor Klasse kann als Beispiel das Gewicht der Zuladung berechnen
class Visitor_Gewicht def initialize @@gesamt=0 end def visit(o) case o.class.to_s when "Person" p "Gewicht #{o.weight}" @@gesamt+=o.weight when "Ladung" p "Gewicht #{o.weight}" @@gesamt+=o.weight end #case end #def visit def ausgabe @@gesamt end #def ausgabe end #class Visitor
durch zwei Änderung bekommt man das Ergebnis
v2=Visitor_Gewicht.new f.ausgabe(v2) p v2.ausgabe
Ergebnis
"Gewicht 80" "Gewicht 81" "Gewicht 60" "Gewicht 40" "Gewicht 50" 311
Verbesserungsvorschlag yield einsetzen
innerhalb der Klasse yield parameter mit geben
ausserhalb der Klasse Visitorklasse angeben
class Flugzeug attr_accessor :arr def initialize() @arr=Array.new() end #def initialize def ausgabe(v) @arr.each do |ele| ele.accept(v) end #do yield v if block_given? end #def ausgabe def push(o) @arr.push(o) end #def push end #class Flugzeug class Visitor_Gewicht attr_accessor :gesamt def initialize @gesamt=0 end def visit(o) case o.class.to_s when "Person" p "Gewicht #{o.weight}" @gesamt +=o.weight when "Ladung" p "Gewicht #{o.weight}" @gesamt+=o.weight end #case end #def visit def ausgabe @gesamt end #def ausgabe end #class Visitor v2=Visitor_Gewicht.new f.ausgabe(v2){|x|p "Gesamt Zuladung #{v2.ausgabe} #{x.ausgabe} #{x.gesamt} "}