The Fore programming language is an object-oriented language. Classes are used to describe objects, store data and implement work algorithms. Class definition includes constants and fields that store object data and class members that use this data: constructors, properties, methods (procedures/functions) and events.
Each class member and the class itself can have an access modifier that determines whether it can be used in other code blocks.
Public Class TUserInfo: Object
//Fields to store values inside class object
_FirstName, _LastName: String;
//Object constructor
Public Constructor Create(Name: String = "");
Begin
_FirstName := Name;
End Constructor Create;
//Object properties
Public Property FirstName: String
Get
Begin
Return _FirstName
End Get
Set
Begin
_FirstName := Value
End Set
End Property FirstName;
Public Property LastName: String
Get
Begin
Return _LastName
End Get
Set
Begin
_LastName := Value
End Set
End Property LastName;
//Methods that are available only inside class
Sub Serialize;
Begin
//...
End Sub Serialize;
Sub Deserialize;
Begin
//...
End Sub Deserialize;
End Class TUserInfo;
To determine custom classes, inherit them from a class. As a parent class, the Object basic class can be used or the already determined custom class. By default, the class has the Private access modifier. The class can implement a number of interfaces. This means that a class must contain implementation of all the members described in interfaces. The class that inherits from some class also inherits all parent class' members. Visibility scope is also inherited.
The class prior description is absent. Any class can be used if it is described in this unit or in any of the imported units. In this case any class parent must be determined before it is inherited by the descendant classes.
When a child class contains a member (method or property) with the same signature as the parent class, this member is considered as redetermined. This means that when this member is called via the child class, the system will use the new redetermined version instead of the one determined in parent class. After the class member is redetermined, it should have access level not lower than access level in the parent class.
If one needs to call member implementation from the parent class in the child class, one needs to use the Inherited keyword.
Sub Main;
Var
cA, cB: A;
Begin
// Class A
cA := New A.Create;
cA.TestSub;
cA := New A.CreateA(50);
Debug.WriteLine("cA.TestProp = " + cA.TestProp.ToString);
cA.TestProp := 150;
Debug.WriteLine("------------");
// Class B
cB := New B.CreateB(200);
cB.TestSub;
Debug.WriteLine("cB.TestProp = " + cB.TestProp.ToString);
cB.TestProp := 250;
End Sub Main;
Public Class A: Object
_TestProp: Integer;
Public Constructor Create;
Begin
Debug.WriteLine("Constructor Create. Class A");
End Constructor Create;
Public Constructor CreateA(A: Integer);
Begin
Create; // Call the Create constructor
_TestProp := A;
Debug.WriteLine("Constructor CreateA. Class A. Param = " + A.ToString);
End Constructor CreateA;
Public Property TestProp: Integer
Get
Begin
Debug.WriteLine("Get TestProp. Class A");
Return _TestProp;
End Get
Set
Begin
Debug.WriteLine("Set TestProp. Class A");
_TestProp := Value;
End Set
End Property TestProp;
Public Sub TestSub;
Begin
Debug.WriteLine("TestSub. Class A");
End Sub TestSub;
End Class A;
Public Class B: A
_TestProp: Integer;
Public Constructor CreateB(B: Integer);
Begin
Inherited CreateA(100); // Call constructor from the A class
_TestProp := B;
Debug.WriteLine("Constructor CreateB. Class B. Param = " + B.ToString);
End Constructor CreateB;
Public Property TestProp: Integer
Get
Begin
Inherited TestProp; // Call get part of the property from the A class
Debug.WriteLine("Get TestProp. Class B");
Return _TestProp;
End Get
Set
Begin
Inherited TestProp(Value); // Call set part of the property from the A class
Debug.WriteLine("Set TestProp. Class B");
_TestProp := Value;
End Set
End Property TestProp;
Public Sub TestSub;
Begin
Inherited TestSub; // Call the TestSub procedure from the A class
Debug.WriteLine("TestSub. Class B");
End Sub TestSub;
End Class B;
To get a link to the object, for which this method is called, within the class method use the Self identifier. The predefined Self identifier is relevant only for class methods, attempts to use it elsewhere in the program result in a compilation error.
The Shared directive specifies that this method or field are a class method or a class field respectively (static class members). Static methods and static fields are not a part of a particular class instance. Regardless of the number of created class instances, there is only one copy of the static field. Static fields start existing after they are referred to for the first time and stop existing after the application domain is shut down.
NOTE. Values of static fields are unique within different connections to the same repository.
Non-static members can use any static or non-static class members. Static members can use only static class members. The Self identifier can be used to address static members within a class or it is possible to simply indicate the static member name.
The Final directive specifies that this method cannot be redefined in the children of this class.
Class SampleClass: Object
Private Shared Temp: Integer;
Public Shared Sub Test;
Begin
Temp := TestEx(1);
//...
End Sub Test;
Public Shared Function TestEx(Index: Integer): Integer;
Var
i: Integer;
Begin
//...
Return i;
End Function TestEx;
Public Sub CreateSettings(Count: Integer);
Begin
//...
If Count < 1 Then
//Call method via Self
Self.Test;
Else
//Call method without using Self
Temp := TestEx(Count);
End If;
End Sub CreateSettings;
Public Final Property GetValue: Integer
Get
Begin
//...
Temp := Correct(Temp);
//...
Return Temp;
End Get
End Property GetValue;
Private Function Correct(Value: Integer): Integer;
Var
i: Integer;
Begin
//...
Return i;
End Function Correct;
End Class SampleClass;
Only delegates can be used as an event type. Delegates determine what kind of signature a method should have to be a handler of the specified event. An assignation operation is only available for the events with a method name in its right part. The method signature must match the delegate signature. The assignation operation is used to assign a new event handler.
See also:
Fore Language Guide | Creating Objects | Class Properties | Delegates and Events | Interfaces