Метод - это член класса, который реализует определенные вычисления или действия над объектом или классом. К методам относятся процедуры (выполняют какие-либо вычисления, не возвращают результат) и функции (выполняют какие-либо вычисления и возвращают результат).
В 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 <> 0) And (o <> Null) Then
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;
Метод является корректным если выполняются все последующие условия:
Определение содержит допустимую комбинацию модификаторов доступа.
Каждый модификатор встречается в определении не более одного раза.
Определение содержит не более одного из трех следующих модификаторов: Shared, Virtual и Override.
Определение содержит не более одного из следующих модификаторов: New и Override.
Если определение содержит модификатор Abstract оно не должно содержать следующих модификаторов: Shared, Virtual и Final.
Если определение содержит модификатор Private оно не должно содержать следующих модификаторов: Virtual, Override и Abstract.
Если определение содержит модификатор Final, то оно также содержит модификатор Override.
При определении абстрактных методов указывается только заголовок метода, определение всех остальных методов включает в себя тело метода, которое содержит операторы выполняемые при вызове метода.
Имя и список формальных параметров метода определяют его сигнатуру.
Сигнатура метода может включать в себя список формальных параметров, последний параметр может быть параметром-массивом.
Существует четыре вида формальных параметров:
Параметры, передаваемые по значению. Параметр, определенный без модификаторов, является параметром передаваемым по значению. Параметр, передаваемый по значению, соответствует локальной переменной, которая получает свое начальное значение из соответствующего аргумента, переданного при вызове метода. Аргумент, передаваемый в качестве значения параметра передаваемого по значению, должен иметь тип, который может быть неявным образом приведен к типу параметра. Допустимо в теле метода присваивать новые значения параметру, передаваемому по значению. Данные изменения носят локальный характер и не влияют на аргумент переданный в вызове метода.
Параметры, передаваемые по ссылке. Параметр, объявленный с модификатором Var, является параметром, передаваемым по ссылке. Параметр, передаваемый по ссылке, не создает новой ячейки памяти. Вместо этого он представляет место в памяти выделенное для хранения переменной, которая была передана в качестве аргумента при вызове метода. Аргумент, передаваемый в качестве значения ссылочного параметра, должен быть переменной того же типа, что и тип параметра.
Выходные параметры. Параметр, объявленный с модификатором Out, является выходным параметром. Аналогично параметрам, передаваемым по ссылке, выходной параметр не создает новой ячейки памяти. Вместо этого он представляет место в памяти выделенное для хранения переменной, которая была передана в качестве аргумента при вызове метода. Аргумент, передаваемый в качестве значения выходного параметра, должен быть переменной того же типа, что и тип параметра. Значение выходного параметра изначально не определено. Оно должно быть определено до возврата из функции.
Параметры-массивы. Параметр, объявленный с модификатором ParamArray, является параметром-массивом и позволяет определить метод с переменным количеством параметров. Параметр такого вида обязательно должен быть последним в списке параметров метода, а также тип его должен быть одномерным массивом. Передача аргументов методу с переменным количеством параметров может производиться одним из следующих способов:
В качестве аргумента может быть передано значение выражения, тип которого может быть неявным образом приведен к типу параметра-массива.
В качестве аргумента может быть передано ноль или более значений, каждое из которых имеет тип неявно приводимый к типу элементов массива. В этом случае при вызове метода создается экземпляр массива, содержащий переданные в качестве аргументов значения, и используется в качестве значения параметра.
За исключением возможности передачи переменного количества аргументов параметры-массивы ничем не отличаются от параметров, передаваемых по значению.
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(1, Var Result);
Obj.B(Out Result);
Arr[0] := 1;
Arr[1] := 2;
Arr[2] := 3;
Obj.C(Arr);
End Sub;
Тело метода состоит из блока операторов. Абстрактные методы не имеют реализации соответственно определения таких методов не содержат тела.
В случае если метод не возвращает значения, то не допустимо в его теле использовать оператор возврата Return с указанием возвращаемого значения. В случае если для метода определено возвращаемое значение, то каждый оператор возврата в теле такого метода должен содержать выражение, тип которого может быть неявно приведен к типу возвращаемого значения.
См. также: