In this article:

Class Inheritance

Inherited

Self

Static and Completed Class Members

Class Events

Classes

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;

Class Inheritance

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.

Inherited

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;

Self

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.

Static and Completed Class Members

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;

Class Events

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