Если определение метода содержит модификатор Virtual, то такой метод называется виртуальным. В противном случае метод является невиртуальным.
Реализация невиртуального метода инвариантна по отношению к типу объекта, для которого производится вызов метода. Реализация виртуального метода может быть изменена в производных классах. Процесс изменения реализации унаследованного виртуального метода в производном классе называется переопределением этого метода.
При вызове виртуального метода во время выполнения программы производится определение реального типа объекта для которого произведен вызов метода и выбор соответствующей реализации виртуального метода. В противоположность этому для невиртуальных методов используется тип объекта, определенный во время компиляции.
Вызов метода c именем N со списком аргументов A для экземпляра, тип которого во время компиляции определен как C, а реальный его тип R, выполняется следующим образом:
Вначале выполняется процедура разрешения перегруженных методов для C, N и A и выбирается определенный метод M из множества методов С (определенных в нем или унаследованных).
Если метод M является невиртуальным, то он и вызывается.
Если метод M является виртуальным, то вызывается самая последняя его реализация относительно класса R.
Для каждого виртуального метода определенного в классе или унаследованного им существует так называемая самая последняя реализация этого метода по отношению к данному классу. Самая последняя реализация виртуального метода M по отношению к классу R определяется следующим образом:
Если класс R содержит первичное определение виртуального метода M, тогда этот метод и является самой последней реализацией.
В противном случае если класс R содержит переопределенную реализацию метода М, тогда эта реализация является самой последней реализацией метода M.
В противном случае самой последней реализацией метода M по отношению к классу R является та же реализация этого метода, что и самая последняя реализация метода М по отношению к классу, который является родительским для R.
Если реализация виртуального метода содержит выражение доступа к базовому члену 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;
См. также: