Виртуальные методы

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

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

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

Вызов метода c именем N со списком аргументов A для экземпляра, тип которого во время компиляции определен как C, а реальный его тип R, выполняется следующим образом:

Для каждого виртуального метода определенного в классе или унаследованного им существует так называемая самая последняя реализация этого метода по отношению к данному классу. Самая последняя реализация виртуального метода M по отношению к классу 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;

См. также:

Методы | Доступ к базовому классу