Sage-Code Laboratory
index<--

EVE Classes

A class is a composite data type. It implement properties and methods required to create objects. Objects are state machines that are instantiated on demand and released from memory when they are no longer needed.

The most important characteristics of objects are:

Bookmarks:

Object Instances

Objects are composite data types. You can declare them as variables. An object instance is a variable of type Object. This is actually a class, that is why it starts with uppercase.

You can create object instance using default constructor. This is a list of attribute-value pairs: (attribute:value, ...). An Object is a reference to a data structure that is created by using the default constructor. The default constructor accept a list of parameters, you do not have to specify the constructor name, just the list of parameters.

Pattern:

Initialize an object by using an object literal.

# define an object instance
variable
    Object object_name = (attribute:value, ...);

Alternative:

Initialize an object by using an explicit constructor call.

#define an object instance
variable
    Object object_name; // create a Null object
process    
    // create object using Object constructor
    object_name = Object(attribute:value, ...);
    ...    

Note: One object instance can receive attribute names that do not exist and bind values to them using column ":" symbol. Default constructor will create new attributes automatic and set-up an implicit data type using type inference. However after object is created the structure is locked: no other attributes can be added.

Class constructor

You can create more complex objects by using a class constructor. This start with keyword "class". This makes special subroutine that can create an object. The object name that is going to be created is an implicit output parameter, that is called "self" and that is available without declaring it.

class ClassName(parameters):
    ** object attributes
    ...
    ** object methods  
    ...
static
    ** class attributes
    ...
    ** class methods
    ...
create
    ** call object default constructor
    self := Object(object_attribute:argument,...);
    ... 
remove
    ** object release region
    ...
return;

Notes: In EVE a "class" is an executable block of code similar to a routine while in Java a class is a data structure that need a constructor method to function properly. I think is better to consider the class as a factory. Objects are factory products, but objects can receive maintenance from a factory. Son in EVE a class can also perform object maintenance.

Conditional constructor

A class can have a single constructor. A constructor can use decision statements based on parameter values to create "object" in different ways based on conditions. This is in EVE a constructor can be complex.

...
create
    ** conditional construction
    if condition then
        self := Object(some_arguments);
    else
        self := Object(other_arguments);
    end if;
return;

Constructor parameters

A class constructor can have parameters that receive values during initialization. You can define optional parameters with default values using pair notation like (TypeName param_name = value). Parameters can receive values using a constructor call, that is similar to a routine call. Parameters can be also assigned using JSON literals.

Syntax:

# define a class with prameters
class ClassName(parameters):
    ** class body
    ....
return;

routine main:
    ** declare null object of type ClassName
    ClassName object_name; 
process
    ** instantiate object using constructor
    object_name := ClassName(param:value,...);
    ...
return;

Class Instances

Class instances are also called objects. These are more advanced objects, they can have custom methods and private attributes that a simple object can not have.

Objects  can be declared and initialized in a single statement using a class constructor. Complex objects can be initialized only by using a user define constructor and not by using the default constructor.

Syntax:

This is how you create a class instance:

objectName := ClassName(arguments);

The object_name from previous example, is the current instance that is created using implicit constructor. Object can be initialized explicit in the creation region of the class using this syntax:

Syntax:

Next we use object name "self" that is the implicit object name, reserved by EVE. This is is the result of class constructor. It is similar to the "result" variable used in sub-routines. The self object is created explicit using an assign statement like:

self := SuperClass(arguments);

Note:

Attributes

A class can have object attributes and class attributes. In other languages, these are called properties or fields. They represent actually states of an object. We stick with the term attributes:

Object attributes

To access object attributes we can use dot notation:

object_name.object_attribute;

Now we know how to instantiate a class and create objects of the same type. Once you have defined a class, this do not know anything about it's objects. You can not ask the class anything.

Class attributes

For a class, you can define static attributes and methods. That's the secret: a class is actually a singleton object. This is holding the class states. Each attributes defined in the "static" region belong to the class singleton object.

You can access all static members without instantiation of the class. But you can also access class members using the object qualifier. Both will point to the same states also called class attributes.

 # accessing static attributes
ClassName.class_attribute;   // using the class name 
object_name.class_attribute; // using the object name

Class Tree There is a special class that has name "Object" and represents the "root" class. Each classes can grow from Object or from other "base class" forming a "class tree". Like a real tree the class hyerarchy has a single root.

Example:

This example define a Point class with two parameters. The parameters have default values so they are optional when you create a point

# define a Point class
class Point(Double x = 0, y = 0):
    Double .x, .y; //public attributes
create
    .x := x;
    .y := y;
return;

routine main:
    Point: p1, p2; //declare two Null points 
process
    **initialize the points
    p1 := Point(x:1, y:2);    
    p2 := Point(x:2, y:2);    
    print ("p1 = (a:#n, b:#n)" ? (p1.a,p1.b));
    print ("p2 = (a:#n, b:#n)" ? (p2.a,p2.b));  
return;

Output:

p1 = (a:1, b:1)      
p2 = (a:2, b:2)

Comparing objects

We can use comparison operators: "==" and "=" with objects. First comparison "==" will compare the object location. If the objects have same location they are also equal. Second compare object class and object attributes. If is the same class and all attributes are equal the objects are equivalent.

Example:

In next examples we use a primitive type: Integer, that is actually a class


routine main:
    Integer o = 0, n = 0; // local variables
process  
    o := 1;
    n := 1; 
    
    ** equal values
    expect  (o  == n); 
    expect  not (o <> n); 
    
    ** not the same location
    expect  (o != n);     
    expect  not (o == n); 
return;

Inheritance

EVE has support for inheritance. You can specify a superclass using symbol "<:" that is equivalent of keyword: "extend" used in Java. Using this symbol makes a class that has all attributes and methods of the super-class.

Syntax:

# define a class with prameters
class ClassName(parameters) <: base_class:
    ** class members
    ...
create
    ** call base class constructor
    self := base_class(object_attribute:argument,...);
    ... 
remove
    ** object release region
    ...   
return;

routine main:
    ** declare null object of type ClassName
    ClassName object_name;
process
    ** instantiate object using constructor
    object_name := ClassName(param:value,...);
    ...
return;

Read next: Data Processing