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