Не уверен, что понял Ваш вопрос,
но то, о чём Вы спрашиваете, называется виртуализация вызова (динамическое связывание вызова).
Это общий механизм всех объектно-ориентированных языков.

НЕвиртуальный вызов:
t.Do для случая, если переменная t имеет нерасширяемый тип (просто RECORD). Компилятор генерирует машинный код вида ВЫЗВАТЬ ПРОЦЕДУРУ (АДРЕС ПРОЦЕДУРЫ Do в модуле, где тип объявлен t)

Виртуальный вызов:
t.Do, если переменная t имеет EXTENSIBLE или ABSTRACT-тип.
Комплятор генерирует код вида:
- от объекта t пойти к описателю его типа;
- у описателя типа есть таблица процедур типа, взять там реальный адрес процедуры Do для реального типа объекта t;
- вызвать процедуру по этому полученному реальному адресу процедуры.

Так вызов и попадает сразу на нужную процедуру, в зависимости от фактического типа объекта, на который указывает t (и независимо от того, что сама переменная t имеет базовый, абстрактный тип).