Klassenmethoden sind Funktionen, die in einer Klasse verankert sind. Durch diese kann man oft verwendete Algorithmen aufrufen, um Objekte leichter zu verwalten. Somit besitzt jede Klasse ihre eigenen Methoden.
Durch einen Doppelpunkt nach einem Objekt, kann man auf eine Klassenmethode zugreifen. Das Objekt kann dabei in einer Variable verankert, literal, oder im Stack geladen sein.
my name = "Josef"
out my name:reverse '= "fesoJ" aus
out -10:abs '= 10
out "abc":u case '= "ABC"
out ("a" + "b" + "c"):reverse '= "cba"
Werden zwei Doppelpunkte angegeben, so greift man auf die Klasse des Headers zu (= Superklasse). Mit dem Header ist das Trägerobjekt einer Variable, einer Gruppe oder einer Funktion gemeint. Man kann somit z.B. ein Objekt umbenennen, oder den Block einer Funktion auslesen und überschreiben.
my name = "Josef"
my name::rename("otherName") 'Zugriff auf die Superklasse
out other name '= "Josef"
myself{ name = "Josef"; age = 16 }
myself::clear
out myself 'Gibt myself{} aus, da die Gruppe geleert wurde
sum(a, b) return a + b
out sum::block 'Gibt { pop a, b; return a + b } aus
Jede der folgenden optionalen Klassenmethoden wird automatisch zu einem bestimmten Ereignis aufgerufen und hat am Anfang des Namens ein Unterstrich. Die Referenz this
ist in jeder Klassenmethode auf das jeweilige Objekt der Klasse gesetzt. In diesem Objekt sind alle Instanz-Variablen aufgestellt.
_new()
_new
ist der Konstruktor einer Klasse. In dieser Funktion werden alle Instanz-Variablen definiert.
my class{
_new(){
this\x = 0
this\y = 0
this\z = 0
}
}
_def(...)
Wird eine Parameterliste bei der Definition eines Objekts angegeben, so werden diese Parameter an die _def
-Funktion übergeben. Somit ist die sofortige Angabe von Werten möglich.
person{
_new(){
this def name.s, age.i
}
_def(name.s, age.i){
this\name = name
this\age = age
}
}
mr x.person("Mr. X", 32) 'Ruft "_new" und danach "_def" auf
_del()
_del
ist der Dekonstruktor eines Objekts. In dieser Funktion können Aufräumarbeiten erledigt werden, falls welche nötig sind.
_true?()
Diese Klassenmethode wird aufgerufen, wenn geprüft werden soll, ob das Objekt "wahr" oder "falsch" ist. Dies ist z.B. für die Auswertung von Aussagen bei "If"-Zweigen nötig.
person{
...
_true?(){
(#true) if(this\name <> "Unknow") else(#false)
}
}
out person("Unknow", 28) '= False
_set(other)
Wird dem jeweiligen Objekt ein Wert zugewiesen (durch =
), dann wird diese Funktion aufgerufen. other
ist der Wert, der rechts vom Gleichheitszeichen ausgewertet wurde. Diese Funktion wird aber auch aufgerufen, wenn ein fremdes Objekt in die Klasse des neu erstellten Objekts umgewandelt werden soll.
point{
...
_set(other&){
if(other::class == point){
this\x = other\x
this\y = other\y
}else if(other::class == integer or other::class == float){
this\x = other
this\y = other
}
}
}
my pos as point
my pos = point(3, 4)
out my pos '= (3|4)
my pos = 0
out my pos '= (0|0)
out 5 as point '= (5|5)
Zur verbesserung der Ausführungs-Geschwindigkeit soll other
als Referenz definiert werden.
_args(...)
Diese Methode wird aufgerufen, sobald eine Eckige Klammer nach dem Objekt erwähnt wird. In dieser stehen die Parameter, die an diese Funktion weitergeleitet werden. Oftmals nutzt man diese Funktion, um über einen Index auf Attribute des jeweiligen Objekts zuzugreifen.
_args(index.i){
if(index == 0){
return this\x
}else if(index == 1){
return this\y
}else if(index == 2){
return this\z
}
}
...
out my vector[1] 'Gibt den Wert der "y"-Variable aus
_vec()
Für alle undefinierten Operationen der jeweiligen Klasse, wird diese optionale Methode aufgerufen, die einen Wert zurückgibt, mit dem gerechnet werden soll. Dies ist z.B. nützlich, wenn ein Objekt einige Daten besitzt, die bei einer vektoriellen Operation nicht modifiziert werden sollen.
player{
_new(){ this def name.s, points.i }
_def(){ this pop }
_form(){ "#(name): #(points)" }
_vec(){ points }
}
def me.player("Josef", 180),
com.player("COM1", 200)
out me + com '= 380 und nicht "JosefCOM1: 380"
Um trotzdem Objekte vollständig operieren zu können, muss man sie als klassenlos behandeln, indem man an die Objektnamen ein Backslash anhängt.
me\ = com\
out me '= COM1: 200
_form()
Mittels dieser Methode soll es möglich sein, ein Objekt lesbar oder auch nur übersichtlich auszugeben, indem das Ergebnis dieser Methode verwendet wird. Dies tritt z.B. automatisch bei out
auf.
_form(){
return "(" << this\x << "|" << this\y << "|" this\z << ")"
}
...
out vector(1, 2, 3) 'Zeigt "(1|2|3)"
Durch das Schlüsselwort method
lässt sich eine Klassenmethode auf eine übersichtlichere Weise angeben. Nach diesem Schlüsselwort wird entweder der Name der Klassenmethode ohne Unterstrich angegeben, oder ein Operator. Falls die "friend"-Methode eines Operators verwendet werden soll, so setzt man das Schlüsselwort friend
vor dem Operator.
user{
method new(){
this def nickname.s, karma.i
}
method def(){
this pop
}
method ++(){
karma++
}
method --(){
karma--
}
method <<(){
return "#(nickname) : #(karma)"
}
}
friend
wird nur innerhalb von method
als Schlüsselwort interpretiert.