継承、仮想メソッド、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;のみ記述
// 犬のサブクラス、動物を継承し鳴き声をオーバーライド
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
オブジェクトを安全に解放、2つの処理を1つにまとめます:
- オブジェクトの
Freeを呼び出しメモリを破棄; - 変数を
nilに代入し、ダングリングポインタを防止。

上記コードではサブクラスTDogのオブジェクトをTAnimal型変数Petに格納しています。PetからCryを呼び出す際、TAnimalのCryではなくTDog内のCryが実行されます。これがポリモーフィズムです。
Cry; virtual:親クラスメソッドを仮想とし、実行時ポリモーフィズムを有効に;- サブクラスは
overrideでCryを上書き; - 変数宣言型は
TAnimalだが実体はTDogなので、犬の鳴き声処理が自動実行される。
virtual付きメソッド:コンパイラは実行時にオブジェクトの実際の型に基づき対応するメソッド実装を解決します。
virtual、overrideを削除した場合
2回の呼び出しがいずれも親クラスのメソッドを実行します

上図はvirtual、overrideを削除した後の画面です

出力はすべてTAnimalの実装となる
コンパイラは変数の宣言型TMyClassのみ参照し、オブジェクトの実行時型を無視します。
- 通常メソッドは既定で非仮想、
virtualを付加すると仮想メソッドになる; - サブクラスで親の仮想メソッドを上書きするには
overrideが必須、無いとコンパイラが警告を出力; - 親クラスの同名仮想メソッドを隠蔽し上書きしない場合は
reintroduceを使用(混乱を招くため非推奨)、C#のnewキーワードに相当
Previous: クラスとは何か
Next: コンストラクタとデストラクタ