In object-oriented programming class is a set (a transitive closure) of types bound by the relation of inheritance. It is said that all types derived from some base type T and the type T itself form a class T.

The first type T from the class T sometimes is called the root type of the class.

A class of types itself, as a type, has the values and operations of its own.
The operations of are usually called methods of the root type.
Both operations and values are called  polymorphic.

A polymorphic operation (method) selects an implementation depending on the actual specific type of the polymorphic argument.

The action of choice the type-specific implementation of a polymorphic operation is called dispatch. Correspondingly, polymorphic operations are often called dispatching or virtual.
Operations with multiple arguments and/or the results of the class are called multi-methods.
A further generalization of is the operation with arguments and/or results from different classes.

 single-dispatch languages are those that allow only one argument or result to control the dispatch. Usually it is the first parameter, often hidden, so that a prefix notation x.f() is used instead of mathematical f(x).
 multiple-dispatch languages allow many arguments and/or results to control the dispatch.


A polymorphic value has a type tag indicating its specific type from the class and the corresponding specific value of that type.
This type is sometimes called the most specific type of a [polymorphic] value.
The type tag of the value is used in order to resolve the dispatch.
The set of polymorphic values of a class is a transitive closure of the sets of values of all types from that class.

In many  OO languages
the type of the class of T and T itself are considered equivalent.
In some languages they are distinct (like in Ada).
When class T and T are equivalent, there is no way to distinguish
polymorphic and specific values.



Task

Create a basic class with a method, a constructor, an instance variable and how to instantiate it.




 
MODULE Point;
IMPORT
	Strings;
TYPE
	Instance* = POINTER TO LIMITED RECORD
		x-, y- : LONGINT; (* Instance variables *)
	END;
 
	PROCEDURE (self: Instance) Initialize*(x,y: LONGINT), NEW;
	BEGIN
		self.x := x;
		self.y := y
	END Initialize;
 
	(* constructor *)
	PROCEDURE New*(x, y: LONGINT): Instance;
	VAR
		point: Instance;
	BEGIN
		NEW(point);
		point.Initialize(x,y);
		RETURN point
	END New;
 
	(* methods *)
	PROCEDURE (self: Instance) Add*(other: Instance): Instance, NEW;
	BEGIN
		RETURN New(self.x + other.x,self.y + other.y);
	END Add;
 
	PROCEDURE (self: Instance) ToString*(): POINTER TO ARRAY OF CHAR, NEW;
	VAR
		xStr,yStr: ARRAY 64 OF CHAR;
		str: POINTER TO ARRAY OF CHAR;
	BEGIN
		Strings.IntToString(self.x,xStr);
		Strings.IntToString(self.y,yStr);
		NEW(str,128);str^ := "@(" +xStr$ + "," + yStr$ + ")";
		RETURN str
	END ToString;
END Point.
 