Aby uzyskać metodę wirtualną lub dynamiczną, należy odpowiednio dołączyć dyrektywę virtual lub dynamic do jej deklaracji. Metody wirtualne i dynamiczne, w odróżnieniu od statycznych, mogą być pokrywane w klasach potomnych. Kiedy wywoływana jest pokryta metoda, do aktywowania wybierana jest jej implementacja z aktualnego (runtime) typu klasowego lub obiektu użytego w wywołaniu — nie zaś typu zadeklarowanej zmiennej.
Aby pokryć metodę, należy redeklarować ją z dyrektywą override. Deklaracja pokrywająca musi odpowiadać deklaracji metody w klasie-przodku w zakresie kolejności i typu parametrów metody, oraz typu rezultatu (jeśli taki jest).
W następującym przykładzie, metoda Draw zadeklarowana w klasie TFigure jest pokryta w dwóch potomnych klasach.
type
TFigure = class
procedure Draw; virtual;
end;
TRectangle = class(TFigure)
procedure Draw; override;
end;
TEllipse = class(TFigure)
procedure Draw; override;
end;
Przyjmując te deklaracje, następujący kod ilustruje efekt wywołania wirtualnej metody poprzez zmienną, której aktualny typ zmienia się w czasie działania programu.
var Figure: TFigure; begin Figure := TRectangle.Create; Figure.Draw; // aktywuje TRectangle.Draw Figure.Destroy; Figure := TEllipse.Create; Figure.Draw; // aktywuje TEllipse.Draw Figure.Destroy; end;
Tylko wirtualne i dynamiczne metody mogą być pokrywane. Wszystkie metody, mogą być przeładowywane (overload).
Metody wirtualne i dynamiczne są semantycznie równoważne. Różnią się tylko sposobem wywoływania metody w czasie działania programu. Metody wirtualne optymalizowane są pod względem szybkości, podczas gdy metody dynamiczne optymalizowane są pod względem rozmiaru kodu.
W ogólności, metody wirtualne stanowią efektywniejszą drogę do implementowania polimorfizmu. Dynamiczne metody są użyteczne kiedy klasa bazowa deklaruje wiele pokrywalnych metod, które są dziedziczone przez wiele klas potomnych w aplikacji, ale są tylko okazjonalnie pokrywane.
Pokrywanie versus ukrywanie