The most important characteristics of objects are:
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.
Initialize an object by using an object literal.
# define an object instance variable Object object_name = (attribute:value, ...);
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.
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.
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;
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.
# 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 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.
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:
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);
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:
To access object attributes we can use dot notation:
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.
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.
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;
p1 = (a:1, b:1) p2 = (a:2, b:2)
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.
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;
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.
# 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