상속, 가상 메서드, 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
객체 안전 해제, 두 단계를 하나로 합침:
- 객체의
Free를 호출해 메모리 소멸; - 변수를
nil로 초기화해 댕글링 포인터 방지.

위 코드는 서브클래스 TDog 객체를 TAnimal 타입 변수 Pet에 저장합니다. Pet으로 Cry를 호출할 때 TAnimal의 Cry가 아닌 TDog 내 Cry가 실행되는데 이것이 다형성입니다.
Cry; virtual부모 메서드를 가상으로 표시해 런타임 다형성 활성화;- 서브클래스는
override로Cry재정의; - 변수 선언 타입은
TAnimal지만 실제 객체는TDog이므로 개 울음 메서드가 자동 실행.
virtual 표시 메서드: 컴파일러가 런타임에 객체의 실제 타입에 맞춰 해당 메서드 구현을 매칭합니다.
virtual와 override를 삭제하면
두 번의 호출 모두 부모 클래스 메서드가 실행됨

위 이미지는 virtual, override를 삭제한 후의 결과입니다

출력값이 전부 TAnimal 내 구현에서 나옴
컴파일러는 변수 선언 타입 TMyClass만 인식하고 객체 실제 런타임 타입은 무시합니다.
- 일반 메서드는 기본적으로 비가상,
virtual을 붙여야 가상 메서드가 됨; - 서브클래스에서 부모 가상 메서드를 재정의하려면
override필수, 없으면 컴파일러 경고 발생; - 부모 동일명 가상 메서드를 가리고 재정의하지 않으려면
reintroduce사용 (혼동 유발로 권장하지 않음), C#의 new 키워드와 동일