In diesem Kapitel wird eine beispielhafte Klasse für 2D Objekte implementiert. D.h. es befinden sich zwei Instanz-Variablen - in diesem Fall "x" und "y" - die durch eine Klasse schneller behandelt werden können. Das Kapitel soll deutlich machen, wie stark objektorientiert Operno ist und welche Möglichkeiten damit offen sind.
Die Klasse nennen wir "point", da meistens Punkte als Objekte verwendet werden, anstatt Vektoren und andere Größen. Mittels "point" sollen wir die Möglichkeit besitzen, wichtige Operationen mit Positionen auszuführen und spezielle Befehle zur schnelleren Behandlung zu besitzen:
Zuerst definieren wir den Konstruktor "_new" und die Klassenmethode "_def" für die Sofortdefinition:
def point{
method new(){
this\x = 0.0
this\y = 0.0
}
method def(x, y){
this\x = x
this\y = y
}
}
Operno ist aber auch flexibel genug, um den oberen Code auch kürzer zu gestalten:
def point{
method new() this def x.f, y.f
method def() this pop
}
Probieren wir mal gleich die neue Klasse aus:
a.point(1 , 2.2)
b.point(-2.5, 10 )
out a, b
Folgende Ausgabe wird durch die letzte Anweisung erzwungen:
point{
x = 1
y = 2.2
}
point{
x = -2.5
y = 10
}
Zwar kann man deutlich die Werte der zwei Objekte ablesen, jedoch wollen wir auch die Ausgabe kurz gefasst haben. Dies können wir durch eine Ausgabe-Methode form
(oder auch <<
) erledigen. Der Rückgabewert dieser Klassenmethode wird in der Ausgabe gezeigt:
pos\method form(){
return "(#(x) | #(y))"
}
Nun bekommen wir jedes Mal die Ausgabe in der Form "(x | y)":
out a '= (1 | 2.2)
out b '= (-2.5 | 10)
Seit Operno 5.30 ist es nicht mehr nötig, vektorielle Operationen zu definieren. Daher können wir sofort Objekte der Klasse "point" operieren:
c.point(3, 4)
d.point(1, -5)
out c + d '= (4, -1)
out d * 2 '= (2, -10)
Das unsere Klasse eher auf Positionen und nicht auf Vektoren basiert, möchten wir für die Subtraktion definieren, dass die Distanz beider Punkte zurückgegeben wird:
pos\method -(other&){
def dx.f, dy.f 'Abstände beider Dimensionen
dx = other\x - x
dy = other\y - y
'Distanz durch den Satz des Pythagoras berechnen:
return (dx² + dy²)//2
}
//2 bedeutet: "die zweite Wurzel". Man kann aber auch "//x anwenden, um die Quadratwurzel aus dem Ausdruck "x" zu berechnen.
Testen wir die Funktion, indem wir Punkte angeben, die exakt den Abstand der Quadratwurzel aus zwei besitzen müssten:
out point(1, 1) - point(2, 2) '= 1.414 ...
Aber auch die Distanz können wir durch einen kompakteren Code berechnen:
pos\method -(other&) = (other\ - this\){ //(x² + y²) }
Ein Backslash nach einem Objekt behandelt alle Unterobjekte klassenlos, damit keine endlose Rekursion entsteht.
Unser Ziel ist nun, eine Funktion in einem bestimmten Intervall als eine Reihe von Punkten abzuspeichern. Dazu definieren wir eine neue Klassenmethode für die Klasse "Block". "Block" verwaltet Gruppierungen von Anweisungen und damit auch Funktionen:
block\generate points(a = -5.0, b = 5.0, steps = 1.0){
def x = a, points[]
while(x <= b){
points:append(point(x, this:call)) 'Y-Wert für "x" ermitteln
x += steps
}
return points
}
Generieren wir nun Punkte für eine Normal-Parabel im Intervall [-3, 3]:
out { x² }:generate points(-3, 3)
Die Ausgabe:
[(-3 | 9), (-2 | 4), (-1 | 1), (0 | 0), (1 | 1),
(2 | 4), (3 | 9)]