Наследование, виртуальные методы, override, reintroduce
Пример наследования классов
Object Pascal поддерживает наследование и виртуальные методы. В примере ниже класс TDog наследует TAnimal:
TDog — подкласс (производный класс), TAnimal — родительский класс (базовый класс)
program AnimalDemo;
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$codepage utf8}
uses SysUtils;
type
// Родительский класс животных
TAnimal = class
procedure Cry; virtual; // Виртуальный метод: звук животного
end; // Конец определения класса, только end;
// Подкласс Собака, наследует Animal и переопределяет звук
TDog = class(TAnimal)
procedure Cry; override;
end;
procedure TAnimal.Cry;
begin
WriteLn('Животное издает звук');
end;
procedure TDog.Cry;
begin
WriteLn('Гав гав гав');
end;
var
Pet: TAnimal;
begin
// Экземпляр родительского класса
Pet := TAnimal.Create;
try
Pet.Cry;
finally
FreeAndNil(Pet);
end;
// Экземпляр подкласса в переменной родительского класса, полиморфизм работает
Pet := TDog.Create;
try
Pet.Cry;
finally
FreeAndNil(Pet);
end;
end.Code language: JavaScript (javascript)
Результат выполнения
D:\fpcdemo>fpc mydemo.dpr
Free Pascal Compiler version 3.2.2 [2021/05/15] for i386
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Win32 for i386
Compiling mydemo.dpr
Linking mydemo.exe
45 lines compiled, 0.1 sec, 68544 bytes code, 4260 bytes data
D:\fpcdemo>mydemo
Животное издает звук
Гав гав гавCode language: CSS (css)
FreeAndNil
Безопасное освобождение объекта, объединяет два действия:
- Вызов метода
Freeобъекта для очистки памяти; - Присвоить переменной значение
nil, чтобы избежать висячих указателей.

В коде выше объект подкласса TDog хранится в переменной Pet типа TAnimal. При вызове метода Cry через Pet выполняется реализация из TDog, а не из TAnimal — это полиморфизм.
Cry; virtualпомечает родительский метод как виртуальный, включая полиморфизм во время выполнения;- Подкласс переопределяет метод
Cryс помощью ключевого словаoverride; - Переменная объявлена как
TAnimal, но содержит реальный объектTDog, поэтому автоматически запускается лай собаки.
Для методов с модификатором virtual: компилятор подбирает нужную реализацию во время выполнения по реальному типу объекта.
Если убрать модификаторы virtual и override
Оба вызова будут запускать метод родительского класса

На изображении выше показан результат после удаления virtual и override

Весь вывод берется из реализации класса TAnimal
Компилятор учитывает только объявленный тип переменной TMyClass и игнорирует реальный тип объекта во время выполнения.
- Обычные методы по умолчанию не виртуальные, они становятся виртуальными только с модификатором
virtual; - При переопределении унаследованного виртуального метода в подклассе обязательно используйте
override, иначе компилятор выдаст предупреждение; - Используйте
reintroduce, если нужно скрыть одноименный виртуальный метод родителя без переопределения (не рекомендуется, вызывает путаницу), аналог ключевого слова new в C#