100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Object-Oriented Pascal

Learn how Pascal implements classes, inheritance, polymorphism, and constructors/destructors through the `class` type and virtual methods.

Practical PascalIntermediate9 min readJul 10, 2026
Analogies

Classes and Objects in Pascal

Object Pascal (as implemented by Free Pascal and Delphi) introduces the class keyword as a reference type distinct from the older object type. A class is always allocated on the heap and accessed through a reference, so assigning one variable to another makes both point at the same instance rather than copying data. You declare fields, methods, and properties inside a class block, then instantiate with Create, which is really just a constructor method inherited from TObject.

🏏

Cricket analogy: A class is like a franchise such as Mumbai Indians: the franchise template defines roles (captain, wicketkeeper), and every season's actual squad is a heap-allocated instance built from that template via a fresh 'Create' each auction cycle.

Inheritance, Virtual Methods, and Polymorphism

Inheritance in Pascal is expressed with type TDog = class(TAnimal), giving TDog every field and method of TAnimal plus whatever it adds. To get true runtime polymorphism you must mark base methods virtual and override them with the override keyword; calling a virtual method through a base-class reference dispatches to the most-derived implementation via the class's virtual method table (VMT). Methods declared without virtual are statically bound, so redeclaring them in a descendant only hides the parent version rather than overriding it — a common source of subtle bugs.

🏏

Cricket analogy: Marking a method 'virtual' is like a captain's 'field placement' instruction that every fielder overrides based on their specific role — a slip fielder and a boundary rider both 'override' the general instruction differently, and the umpire's call always resolves to whichever player is actually standing there.

Constructors, Destructors, and Interfaces

Constructors use the constructor keyword and are conventionally named Create; they can be overloaded with different parameter lists and should always call inherited Create first so the ancestor chain initializes properly, including setting up the VMT pointer. Destructors use destructor Destroy; override; and must call inherited Destroy last, typically wrapped in a try...finally block with FreeAndNil to guarantee cleanup even if an exception occurs mid-construction. Free Pascal also supports interface types, which declare a contract of methods with no implementation; a class implements one or more interfaces and objects can be queried or cast to an interface reference for loosely coupled, COM-style polymorphism with automatic reference counting.

🏏

Cricket analogy: A constructor is like a new player's induction into a team: the academy-level basics (inherited Create) must be completed before the franchise adds its own specific training, and a bad or interrupted induction (an exception mid-Create) means the player never properly takes the field.

pascal
type
  TAnimal = class
  private
    FName: string;
  public
    constructor Create(const AName: string); virtual;
    destructor Destroy; override;
    function Speak: string; virtual;
    property Name: string read FName;
  end;

  TDog = class(TAnimal)
  public
    function Speak: string; override;
  end;

constructor TAnimal.Create(const AName: string);
begin
  inherited Create;
  FName := AName;
end;

destructor TAnimal.Destroy;
begin
  // release any owned resources here
  inherited Destroy;
end;

function TAnimal.Speak: string;
begin
  Result := FName + ' makes a sound';
end;

function TDog.Speak: string;
begin
  Result := FName + ' barks';
end;

var
  A: TAnimal;
begin
  A := TDog.Create('Rex');
  try
    WriteLn(A.Speak); // dispatches to TDog.Speak via VMT: 'Rex barks'
  finally
    A.Free;
  end;
end.

If you forget the override keyword when redeclaring a virtual method, Free Pascal silently hides the parent method instead of overriding it. Calling it through a base-class reference will then run the parent's version, not the derived one — enable {$WARN 5023 ON} or compile with -vw to catch these accidental hides.

  • Pascal classes are heap-allocated reference types; assignment copies the reference, not the object.
  • Mark base methods virtual and derived overrides override to get true runtime polymorphism via the VMT.
  • Methods without virtual/override are statically bound and only hide, rather than override, the ancestor's method.
  • Constructors should call inherited Create first; destructors should call inherited Destroy last.
  • Wrap object lifetime in try...finally with Free/FreeAndNil to guarantee cleanup on exceptions.
  • Interfaces declare method contracts with no implementation and support reference-counted, COM-style polymorphism.
  • TObject is the implicit ancestor of every class, providing Create, Free, ClassName, and other base services.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#PascalStudyNotes#ObjectOrientedPascal#Object#Oriented#Pascal#Classes#OOP#StudyNotes#SkillVeris