uses System.Generics.Collections;
type
TVehicle = class
public
procedure Test;
end;
TCar = class(TVehicle)
end;
TTruck = class(TVehicle)
end;
procedure TVehicle.Test;
begin
//ClassName reports the real type
WriteLn('test ', ClassName);
end;
var
List: TList<TVehicle>;
Vehicle: TVehicle;
begin
//descendants substitute for the base
List := TList<TVehicle>.Create;
List.Add(TVehicle.Create);
List.Add(TCar.Create);
List.Add(TTruck.Create);
for Vehicle in List do
Vehicle.Test;
end.