Τετάρτη 24 Ιουνίου 2020

Revision 32, Version 9.9 Inner Classes Public and Private

This revision has some additions for the same idea about classes with inheritance at source level.  We mace classes in any module/function, and also in class definition as member of class.

A tiny example of private class Alfa, with two classes, where zeta is a beta too. So we make two groups K1 and K2, as members of the group which return the alfa class. The module work is the constructor. We can select one from three groups, each one from a class. First we make alfa as this.alfa(), next we make N from alfa.zeta() (this is public), and then we make the M from alfa.beta()

class work {
Private:
    Class alfa {
        class beta {
            x=10
        }
        class zeta as beta {
            y=20, z=30
        }
        zeta K1, K2
    }
Public:
Class:
    module work(f) {
        alfa=.alfa()
        Print alfa.k1.x, alfa.k1.y, alfa.k1.z
        Print alfa.k2.x, alfa.k2.y, alfa.k2.z
        N=alfa.zeta()
        Print N.x, N.y, N.z
        M=alfa.beta()
        Print M.x
        select case f
        case 1
            This=N
        case 2
            This=M
        else case
            This=alfa
        end select
    }
}
alfa1=work(1)
alfa2=work(2)
alfa3=work(3)
List    ' List of all variables except private

We can do the better from previous because  the is no reason to keep the private class alfa as a member of the final object. So now we place it as a group alfa in the constructor
class work {
Class:
    module work(f) {
        Group alfa {
            class beta {
                x=10
            }
            class zeta as beta {
                y=20, z=30
            }
            zeta K1, K2
        }
        Print alfa.k1.x, alfa.k1.y, alfa.k1.z
        Print alfa.k2.x, alfa.k2.y, alfa.k2.z
        N=alfa.zeta()
        Print N.x, N.y, N.z
        M=alfa.beta()
        Print M.x
        select case f
        case 1
            This=N
        case 2
            This=M
        else case
            This=alfa
        end select
    }
}
alfa1=work(1)
alfa2=work(2)
alfa3=work(3)
List    ' List of all variables except private

New examples:

This is the prv_str example. The line z$ k("hello"), m("yes"). make two groups, k$ and m$ (also as k and m - referneces for k$ and n$). In a class dedinition we can;t use at the rihjt expresions items which we place as members, so to use the class z$ we have to put as  a statement and then we can give the names of groups and possible some parameters for constructor. A string group return a string value (here se don't have a Set { } member for assigning values. Variable counter is global but only until module delta exit from execution. A class: label start a session of not copied members so class Delta start with no members to return; Because in module delta, the constructor, we have a line this=.beta() we place to this, the return of inner class beta(). (the dot means This.beta())


\\ a simple example 2 - class in class in class
\\ creating classes which return string value
class delta {
class:
    class beta {
    Private:
        class z$ {
        private:
            what$
            val=counter
        public:
            value {
                =.what$+str$(.val)
            }
        class:
            \\ constructor
            module z (.what$) {
            counter++
            }
        }
        z$ k("hello"), m("yes")
    Public:
        module doit {
            print .k$, .m$
        }
    }
    \\ constructor
    module delta {
        global counter=500
        b=.beta()
        b.doit
        c=.beta()
        c.doit
        this=.beta()
    }
}
z=delta()
z.doit


This is the javalike example (new in info file, which exist in M2000 setup file). The a=10 parameter in Function super.toString$() has no meaning, included as a joke. Any parameter without initialization produce error, but here we place a default value. We can use ![] (see below the remarks) to pass current stack of values to the calling function.
This is something which M2000 has as a basic idea.  Every statement has three things, a scope (a module and a function hold own scope), a stack of values which can push or read (as LIFO) or use Data to append, (so with Read we can use it as FIFO.), and the input/output object (a layer, console has 34 layer, printer has another one, and each user form, in the private window manager is a layer too - up to 100 layers we can define for 100 user forms- windows). So this language has an environment with many things like event programming, gui programming, functional programming, multitasking programming.

We never put a type for a function, except the $ for strings. Anything which return String has to marked with S (like in Basic). If we place more parameters we don't have an error. In fact some time we need something like this. We have an error if we want to read a number and we find a string. If a functions get two parameters, we can get one, do something and later get the other, or perhaps we can decide to do nothing we the other parameter. The dot in front of .super.tostring$() is the place of hidden This, so we read it like this: This.super.tostring$()  Super isn't a pointer to something. Is a part of name; We can make names with dot between first and any other character;

        Function toString$() {
        =.super.toString$(![])
       }

Update Version (Revision 33).
The moveleftside get a pointer and inside method we can use private variables from the input object which has the same type. Interpreter check all types (not the types of members but the types of classes which a class made.

\\ to bypass a function we can use this
\\ function alfa {=.beta(![])}
\\ [] is the current stack and when we read it, we get a pointer and leave an empty stack as current stack
\\ so anything we pass to alfa() passed to .beta(), the dot is This, so to This.Beta()

\\ here we use toString$() to call super.toString$() without parameters
\\ For modules is very easy because a module get the current stack
\\ so if we have a member Module alfa {.beta} calling alfa 10,20 is like calling .beta 10, 20 (and all other values the current stack have)

\\ Constructors are modules but called from functions so they get the function's stack (a new one)
\\ Also a constructor skip the erasing phase (the function which call the module do this)
\\ We need this because we can expand the This object.


Report {
    there is no super like java super in M2000 when we use inheritance through classes
    see Superclass (example SUP) which is something differnent
    }


class Shape {
private:
    super.X, super.Y
    Function super.toString$(a=10) {
        ="Shape(" + str$(.super.X,"") + ", " + str$(.super.Y,"") + ")"
    }
public:
       Module final setPosition (px, py) {
           .super.X <= px
           .super.Y <= py
       }
        Function toString$() {
        =.super.toString$()
    }
}
class MoveShape {
      Module MoveRelative(xr, yr) {
            .super.X+=xr
            .super.Y+=yr
      }
}
class Circle as MoveShape as Shape {
private:
    radius
public:
    Module setRadius (r) {
        .radius <= r
    }
    Function toString$() {
        = .super.toString$() + ": Circle(" + str$(.radius,"") + ")"
    }
}

class Rectangle as MoveShape as Shape {
private:
    height, width
public:
      Module MoveLeftSide (p as *Rectangle) {
      \\ for same type objects private members are like public
           for This, p {
               .super.X<=..super.X+..width
               .super.Y<=..super.Y
           }
      }
    module setDimensions (h,w) {
        .height <= h
        .width <= w
    }
    Function toString$() {
       = .super.toString$() + ": Rectangle(" + str$(.height,"") + " x " + str$(.width,"") + ")"
    }
}
c =Circle()
r = Rectangle()

r.setPosition 1, 2
r.setDimensions 50, 50
c.setPosition 3, 4
c.setRadius 10
Print r.tostring$()
Print c.tostring$()
r.MoveRelative 100,100
c.MoveRelative -50,-50
Print r.tostring$()
Print c.tostring$()

Report  {
    wokring with pointers like in c++
    pointers in M2000 are objects, so null pointer (pc->0&) isn't a zero, but an empty Group (object)
    }
pc->circle()
pr->rectangle()
pr=>setPosition 1, 2
pr=>setDimensions 50, 50
pc=>setPosition 3, 4
pc=>setRadius 10
Print pr=>tostring$()
Print pc=>tostring$()
\\ we can open up to ten objects (from one to ten dots, normaly one to three)
\\ if we use nestef for object {} also we have up to ten objects in total
\\ every for object {} is an area for temporary definitions, after exit from brackets
\\ any new definition erased.
For pr, pc {
    .MoveRelative 100,100
    ..MoveRelative -50,-50
    Print .tostring$()
    Print ..tostring$()
}
pr2->rectangle()
pr2=>SetDimensions 30, 30
pr2=>MoveLeftSide pr
Print pr2=>toString$()



Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.