Inheritance and Polymorphism
17.1 Inheritance
type
TAnimal = class
protected
FName: string;
public
constructor Create(const AName: string); virtual;
function Speak: string; virtual; // virtual: can be overridden
function Describe: string; // static (non-virtual)
end;
TDog = class(TAnimal)
public
function Speak: string; override;
end;
TCat = class(TAnimal)
public
function Speak: string; override;
end;
constructor TAnimal.Create(const AName: string);
begin
inherited Create;
FName := AName;
end;
function TAnimal.Speak: string; begin Result := '...'; end;
function TAnimal.Describe: string; begin Result := FName + ' says ' + Speak; end; // polymorphic call
function TDog.Speak: string; begin Result := 'Woof'; end;
function TCat.Speak: string; begin Result := 'Meow'; end;
var Animals: TArray<TAnimal> := [TDog.Create('Rex'), TCat.Create('Tom')];
for var A in Animals do
begin
Writeln(A.Describe);
A.Free;
end;17.2 Method Binding Directives
Virtual method table (VMT): faster calls Dynamic method table (DMT): smaller memory, slower calls Override a virtual/dynamic method No implementation (with virtual)
Hide an inherited virtual method intentionally (suppresses the warning)
Can't be overridden further (also on classes: TMyClass = class sealed) message WM_XXX Windows message handler
17.3 Abstract Classes and Type Checks
Creating an instance of a class with abstract methods gives a warning, and calling an abstract method raises EAbstractError.
type
TShape = class abstract
public
function Area: Double; virtual; abstract;
end;
TCircle = class(TShape)
private
FRadius: Double;
public
constructor Create(R: Double);
function Area: Double; override;
end;
if Shape is TCircle then
Writeln('Radius: ', (Shape as TCircle).Radius:0:2); // checked cast (EInvalidCast if wrong)
var C := TCircle(Shape); // unchecked hard cast (fast, unsafe)17.4 Virtual Constructors and Destructors
Destructors must be override of Destroy (always call inherited last). Constructors can be virtual to work with class references (Module 16.4). Components use constructor Create(AOwner: TComponent); override;.