Методы

Метод - это член класса, который реализует определенные вычисления или действия над объектом или классом. К методам относятся процедуры (выполняют какие-либо вычисления, не возвращают результат) и функции (выполняют какие-либо вычисления и возвращают результат).

В Fore.NET доступны следующие виды методов:

Когда определение метода содержит модификатор Shared такой метод называется статическим. Когда модификатора Shared нет в определении метода он называется экземплярным.

Статический метод не оперирует конкретным экземпляром, является ошибкой компиляции использование конструкции Self в статическом методе.

Экземплярный метод оперирует определенным экземпляром класса, который может быть получен посредством конструкции Self.

Если сигнатура метода содержит модификатор Override, это означает что данный метод переопределяет реализацию унаследованного виртуального метода базового класса.

Пример

Class SharedMethod
    Public Shared i: integer;
    Public Shared o: object;
    Shared b: boolean;
    
    Public Shared Sub Reset();
    Begin
        i := 0;
        o := Null;
    End Sub;
    
    Public Shared Function TestObject(): boolean;
    Begin
        If (i <> 0And (o <> NullThen
            b := True;
        Else
            b := False;
        End If;
        Return b;
    End Function;
    
    Public Sub Execute();
    Begin
    End Sub Execute;
End Class;

Sub Test();
Var
    Obj: SharedMethod = New SharedMethod();
Begin
    SharedMethod.Reset();
    ...
    SharedMethod.i := //Установка значения
    SharedMethod.o := //Установка значения
    ...
    If SharedMethod.TestObject() Then
        //Действия, если функция вернула значение True
    Else
        //Действия, если функция вернула значение False
    End If;
    Obj.Execute();
End Sub;

Если сигнатура метода содержит модификатор Virtual, то такой метод называется виртуальным. В противном случае метод является невиртуальным.

Реализация невиртуального метода инвариантна по отношению к типу объекта, для которого производится вызов метода. Реализация виртуального метода может быть изменена в производных классах. Процесс изменения реализации унаследованного виртуального метода в производном классе называется переопределением этого метода.

При вызове виртуального метода во время выполнения программы производится определение реального типа объекта, для которого произведен вызов метода и выбор соответствующей реализации виртуального метода. В противоположность этому для невиртуальных методов используется тип объекта, определенный во время компиляции.

Если реализация виртуального метода содержит вызов Inherited, то управление передаётся к предыдущей реализации данного метода в одном из родительских классов. Если посредством вызова Inherited управление передается к виртуальному методу, то определение вызываемого метода производится относительно того класса, в котором объявлена реализация метода, содержащего вызов Inherited.

Пример

Class A
    Public Virtual Sub Test();
    Begin
    End Sub;
    
    Public Sub Test1();
    Begin
    End Sub Test1;
End Class;

Class B: A
    Public Override Sub Test();
    Begin
    End Sub;
    
    Public Sub Run();
    Begin
        Inherited Test();
    End Sub;
End Class;

Class C: B
    Public Override Sub Test();
    Begin
    End Sub;
    
    New Public Sub Test1();
    Begin
    End Sub Test1;
End Class;

Sub Main();
Var
    p: C = New C();
Begin
    p.Run(); // Вызов метода B.Run, который в свою очередь передаст управление A.Test
    (p As A).Test(); // Вызов последней реализации метода Test - C.Test
    (p As A).Test1(); // Вызов метода A.Test1
End Sub;

Если сигнатура экземплярного метода класса содержит модификатор Final, то такой метод называет завершённым. Определение завершённого метода также обязательно должно содержать модификатор Override. Использование модификатора Final блокирует возможность дальнейшего переопределения метода в производных классах.

Пример

Class A
    Public Virtual Sub Test();
    Begin
    End Sub;
End Class;

Class B: A
    Public Final Override Sub Test();
    Begin
    End Sub;
End Class;

Class C: B
    //При описании данного метода возникнет ошибка компиляции
    //т.к. метод завершён в исходном классе B
    Public Override Sub Test();
    Begin
    End Sub;
End Class C;

Если сигнатура экземплярного метода содержит модификатор Abstract, то такой метод называется абстрактным. Абстрактные методы неявно также являются виртуальными, соответственно не допускается использовать модификатор Virtual в их определении.

Определение абстрактного метода вводит новый виртуальный метод, но не описывает реализацию этого метода. Определения абстрактных методов допустимы только в абстрактных классах. Все неабстрактные классы, являющиеся производными от абстрактного, должны обеспечивать реализацию всех абстрактных методов путем их переопределения.

Является ошибкой компиляции использование абстрактного метода в выражении доступа к базовому классу.

Допустимо определению абстрактного метода переопределять виртуальный метод.

Пример

Abstract Class AbstractMethod
    Abstract Public Sub Test();
    Abstract Protected Function Run(): boolean;
End Class;

Class Sample: AbstractMethod
    b: boolean;
    
    Public Override Sub Test();
    Begin
    End Sub;
    
    Protected Override Function Run(): boolean;
    Begin
        Return b;
    End Function;
End Class;

Метод является корректным если выполняются все последующие условия:

При определении абстрактных методов указывается только заголовок метода, определение всех остальных методов включает в себя тело метода, которое содержит операторы выполняемые при вызове метода.

Имя и список формальных параметров метода определяют его сигнатуру.

Параметры методов

Сигнатура метода может включать в себя список формальных параметров, последний параметр может быть параметром-массивом.

Существует четыре вида формальных параметров:

За исключением возможности передачи переменного количества аргументов параметры-массивы ничем не отличаются от параметров, передаваемых по значению.

Class MethodParams
    //Параметр i передается по значению
    //Параметр j передается по ссылке
    Public Sub A(i: integer; Var j: integer);
    Begin
    End Sub;
    
    //Выходной параметр i
    Public Sub B(Out i: integer);
    Var
        Result: integer;
    Begin
        //Код процедуры
        i := Result;
    End Sub;
    
    //Параметр-массив Arr
    Public Sub C(Paramarray Arr: array Of double);
    Begin
    End Sub;
End Class;

Sub Test();
Var
    Obj: MethodParams = New MethodParams();
    Result: integer;
    Arr: array Of double = New double[3];
Begin
    Obj.A(1Var Result);
    Obj.B(Out Result);
    Arr[0] := 1;
    Arr[1] := 2;
    Arr[2] := 3;
    Obj.C(Arr);
End Sub;

Тело метода

Тело метода состоит из блока операторов. Абстрактные методы не имеют реализации соответственно определения таких методов не содержат тела.

В случае если метод не возвращает значения, то не допустимо в его теле использовать оператор возврата Return с указанием возвращаемого значения.  В случае если для метода определено возвращаемое значение, то каждый оператор возврата в теле такого метода должен содержать выражение, тип которого может быть неявно приведен к типу возвращаемого значения.

См. также:

Классы