## Τρίτη, 10 Ιουλίου 2018

### Πολυμορφισμός

Εδώ υπάρχουν οι απλές εκδοχές:
http://www.rosettacode.org/wiki/Polymorphism#M2000_Interpreter

Εδώ με χρήση γεγονότος σε στατικές ομάδες (groups)

Class PointA {
Event "Print"
\\ property is a group in group with value/set or any of them
\\ interpeter make [x] and [y] as private variabes
\\ so if  we dont make a Set part then we have to use the private to set a read only property
Property x {
Value {
\\  call event "Print", "Read Value X:",Value
}
Set {
call event "Print", "Set Value X:",Value
}
}=0~ ' start value is 0 single
Property Y=0~
Module Print {
Print "Point" , .x, .y
}
Class:
\\ [x] is the private variable behind property
Module PointA (x as single=10, y as single=10) {
swap .[x], x
swap .[y], y
}
}
Class Circle {
Property R=300~ ' type single
Operator "=" (n1) {
\\ we use stack to return true or false
n=group(n1)
if n.x=.x Then if n.y=.y then if n.r=.r then push true : exit
push false
}
Module Print {
Print "Circle", .x, .y, .r
}
Class:
Module Circle {
if match("nn") then {
M=PointA(Number, Number)
'combine This to M, Point replaced from Super
} Else.if match("G") then {
M=PointA()
} Else M=PointA()
M=This
This=M
}
}
Group WithEvents A=PointA(10,3)
Function A_Print (what\$, val) {
Print what\$, val
}
A.Print
Print A.x, A.y
C=Circle(20,10,5)
Print C.x,C.y, C.r
C.Print
D=Circle(A, 100) : D.Print
Group withevents Z=Circle(A) : Z.Print
Function Z_Print (what\$, val) {
Print what\$, val
}
Z.x=20 'call event Z_Print
T=Circle() : T.Print
Def ExprType\$(x)=Type\$(x)
Print Type\$(T.y)="Group", ExprType\$(T.y)="Single"
Print Type\$(T.r)="Group", ExprType\$(T.r)="Single"
F=Z ' also event Z_Print is part of F
Print Type\$(F.r)="Group", ExprType\$(F.r)="Single"
N->F
N=>x=400 ' call event Z_Print
N=>Print
Module Inner (x) {
Print "New value in x"
x=>x=500 ' call event Z_print
x=>Print
Print "change pointer,  now N<>x, but only in Inner Module"
x->Circle(50,50, 1000)
x=>Print
}
Print "by value pass the pointer N"
Inner N
Print "N point to F, with new value in x"
N=>Print
F.Print
Print N=F, F=N ' F is group, N is pointer to group

\\ this is the same as C=F, we get a copy, not a copy of pointer
\\ C is a group, not a pointer to group
C=group(N)
Module Inner (&x) {
x->Circle(50,50, 1000)
}
Print "by reference pass the pointer N"
Inner &N
Print "Now N not point to F"
N=>Print
F.Print
Print "C have the old copy of N, which is same as F"
C.print
Print F =C ' True
Print Z=F ' False
C=Z
Print F =C ' False
Print Z=F ' False
Print C=Z ' True
Z.x=300
F.x=100 ' F use event Z_Print
C.x=400 ' no event for C

Εδώ με χρήση αντικείμενου γεγονότος. Στα αντικείμενα γεγονός προσθέτουμε μια ή περισσότερες συναρτήσεις (μπορούμε να αφαιρέσουμε, να το απενεργοποιήσουμε ή να το ενεργοποιήσουμε). Το στατικό γεγονός στο προηγούμενο παράδειγμα έχει μόνο μια συνδεδεμένη συνάρτηση.

Γενικά τα γεγονότα μπορούν να μην έχουν καμία συνάρτηση εξυπηρέτησης. Όταν γίνονται κλήσεις, και δεν υπάρχουν συναρτήσεις, ο διερμηνευτής τα αγνοεί. Στα στατικά γεγονότα (όπως στο προηγούμενο παράδειγμα), τα γεγονότα περνάνε και στις ομάδες που προκύπτουν από ομάδες, και στην ουσία είναι μόνο ισχνές αναφορές (δεν λογαριάζουν κάποια υπογραφή για τις παραμέτρους, αφού μια μόνο συνάρτηση θα κληθεί, σε αντίθεση με το αντικείμενο γεγονός όπου μπορούν να κληθούν πολλές και οι παράμετροι πρέπει να συμπίπτουν, αριθμητικώς και ποιοτικός - αριθμός ή αλφαριθμητικό). Και στις δυο περιπτώσεις μπορούμε να περνάμε με αναφορά ότι θέλουμε ακόμα και το &Αυτό (&This) που είναι το ίδιο το αντικείμενο.

Class PointA {
Event PrintMe {
}
Property x {
Value {
\\  call event "Print", "Read Value X:",Value
}
Set {
call event PrintMe "Set Value X:",Value
}
}=0~ ' start value is 0 single
Property Y=0~
Module Print {
Print "Point" , .x, .y
}
Class:
\\ [x] is the private variable behind property
Module PointA (x as single=10, y as single=10) {
swap .[x], x
swap .[y], y
}
}
Class Circle {
Property R=300~ ' type single
Operator "=" (n1) {
\\ we use stack to return true or false
n=group(n1)
if n.x=.x Then if n.y=.y then if n.r=.r then push true : exit
push false
}
Module Print {
Print "Circle", .x, .y, .r
}
Class:
Module Circle {
if match("nn") then {
M=PointA(Number, Number)
'combine This to M, Point replaced from Super
} Else.if match("G") then {
M=PointA()
} Else M=PointA()
M=This
This=M
}
}
Function PrintEvent (New W\$, V){
Print W\$, V
}
A=PointA(10,3)
Event A.PrintMe New &PrintEvent()
A.Print
Print A.x, A.y
C=Circle(20,10,5)
Print C.x,C.y, C.r
C.Print
D=Circle(A, 100) : D.Print
Z=Circle(A) : Z.Print

Z.x=20 'call event Z_Print

T=Circle() : T.Print
Def ExprType\$(x)=Type\$(x)
Print Type\$(T.y)="Group", ExprType\$(T.y)="Single"
Print Type\$(T.r)="Group", ExprType\$(T.r)="Single"
F=Z ' also event Z_Print is part of F
Print Type\$(F.r)="Group", ExprType\$(F.r)="Single"
N->F
N=>x=400 ' call event Z_Print
N=>Print
Module Inner (x) {
Print "New value in x"
x=>x=500 ' call event Z_print
x=>Print
Print "change pointer,  now N<>x, but only in Inner Module"
x->Circle(50,50, 1000)
x=>Print
}
Print "by value pass the pointer N"
Inner N
Print "N point to F, with new value in x"
N=>Print
F.Print
Print N=F, F=N ' F is group, N is pointer to group

\\ this is the same as C=F, we get a copy, not a copy of pointer
\\ C is a group, not a pointer to group
C=group(N)
Module Inner (&x) {
x->Circle(50,50, 1000)
}
Print "by reference pass the pointer N"
Inner &N
Print "Now N not point to F"
N=>Print
F.Print
Print "C have the old copy of N, which is same as F"
C.print
Print F =C ' True
Print Z=F ' False
C=Z
Print F=C ' False
Print Z=F ' False
Print C=Z ' True
Z.x=300
F.x=100 ' F use event Z_Print
C.x=400 ' no event for C