Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. Pascal Dictionary
  3. Class Basics

Class Basics

The CLASS declaration in Object Pascal is the fundamental object-oriented feature that groups fields, methods, and properties into a single type. Instances are created with the constructor (Create) and freed with the destructor (Destroy). Inheritance and polymorphism are supported, and all classes implicitly inherit from TObject.

Syntax

{ -----------------------------------------------
  CLASS declaration (TYPE section)
  ----------------------------------------------- }

type
  TClassName = class(TParentClass)
  private
    { fields accessible only from within the class }
    FFieldA : TypeA;
    FFieldB : TypeB;
  public
    { constructor — creates an instance }
    constructor Create(arg: Type);
    { destructor  — frees the instance }
    destructor  Destroy; override;
    { methods }
    procedure MethodName;
    function  FunctionName: ReturnType;
    { properties }
    property PropName: Type read FFieldA write FFieldA;
  end;

{ -----------------------------------------------
  Method implementation (implementation section)
  ----------------------------------------------- }

constructor TClassName.Create(arg: Type);
begin
  inherited Create;        { call the parent class constructor }
  FFieldA := arg;
end;

destructor TClassName.Destroy;
begin
  { release any dynamically allocated resources }
  inherited Destroy;       { call the parent class destructor last }
end;

{ -----------------------------------------------
  Creating and freeing an instance
  ----------------------------------------------- }

var
  obj : TClassName;

begin
  obj := TClassName.Create(arg);
  try
    obj.MethodName;
  finally
    obj.Free;              { safely calls Destroy }
  end;
end.

Syntax Reference

Syntax / KeywordDescription
class(TParentClass)Declares a class. When the parent class is omitted, TObject is automatically inherited.
privateSection for declaring members accessible only from within the class.
publicSection for declaring members accessible from outside the class.
protectedSection for declaring members accessible from the class itself and derived classes.
constructor CreateA special method called automatically when an instance is created. Invoked with TClassName.Create(...).
destructor DestroyA special method called automatically when an instance is freed. Override it with the override keyword.
inheritedCalls the method of the same name from the parent class. Must be called in constructors and destructors.
obj.FreeA safe method that checks for nil before calling Destroy. Use this instead of calling Destroy directly.
try ... finallyEnsures that Free in the finally block is always executed even if an exception occurs.
propertyEncapsulates access to a field using read / write specifiers.
Field naming conventionPrivate fields are conventionally prefixed with F in Object Pascal (e.g., FName).

Common Mistakes

Not calling inherited Create in the constructor

Without calling the parent class constructor, the parent class is not initialized. Make it a habit to call inherited Create; even when inheriting from TObject.

{ Problematic code — inherited Create is omitted }
constructor TFighter.Create(const AName: string);
begin
  { TObject is not initialized because inherited Create; is not called }
  FName := AName;
end;
{ Correct code }
constructor TFighter.Create(const AName: string);
begin
  inherited Create;   { always call the parent constructor first }
  FName := AName;
end;

Memory leak when try..finally is missing

If an exception occurs after obj := TMyClass.Create;, without try..finally, obj.Free is never called and a memory leak occurs. Always use the try..finally..obj.Free..end pattern.

{ Problematic code — Free is not called when an exception occurs }
var
  fighter : TFighter;
begin
  fighter := TFighter.Create('Kyo Kusanagi');
  fighter.PrintInfo;   { if an exception occurs here, fighter.Free is never called }
  fighter.Free;
end.
{ Correct code — finally ensures Free is always called }
var
  fighter : TFighter;
begin
  fighter := TFighter.Create('Kyo Kusanagi');
  try
    fighter.PrintInfo;
  finally
    fighter.Free;   { always executed even if an exception occurs }
  end;
end.

Sample Code

kof_class.pas
{$mode objfpc}
{ kof_class.pas — demonstrates the basics of CLASS in Object Pascal }
{ Represents KOF (The King of Fighters) fighters as classes }
{
  Compile and run:
    fpc kof_class.pas && ./kof_class
}

program kof_class;

type
  TFighter = class(TObject)
  private
    FName     : string;
    FTeam     : string;
    FPower    : Integer;
    FIsActive : Boolean;
  public
    constructor Create(const AName, ATeam: string; APower: Integer);
    destructor  Destroy; override;
    procedure   PrintInfo;
    procedure   SetPower(APower: Integer);
    function    GetGreeting: string;
    property    Name     : string  read FName;
    property    Team     : string  read FTeam;
    property    Power    : Integer read FPower    write FPower;
    property    IsActive : Boolean read FIsActive write FIsActive;
  end;

constructor TFighter.Create(const AName, ATeam: string; APower: Integer);
begin
  inherited Create;
  FName     := AName;
  FTeam     := ATeam;
  FPower    := APower;
  FIsActive := True;
  WriteLn('[Created] ', FName, ' has entered the field.');
end;

destructor TFighter.Destroy;
begin
  WriteLn('[Freed] ', FName, ' has left the field.');
  inherited Destroy;
end;

procedure TFighter.PrintInfo;
begin
  WriteLn('  Name     : ', FName);
  WriteLn('  Team     : ', FTeam);
  WriteLn('  Power    : ', FPower);
  if FIsActive then begin
    WriteLn('  Status   : Active');
  end else begin
    WriteLn('  Status   : Retired');
  end;
end;

procedure TFighter.SetPower(APower: Integer);
begin
  if APower < 0   then APower := 0;
  if APower > 100 then APower := 100;
  FPower := APower;
end;

function TFighter.GetGreeting: string;
begin
  GetGreeting := FName + ' (' + FTeam + ') — entering!';
end;

var
  fighters : array[1..5] of TFighter;
  i        : Integer;

begin
  WriteLn('===== KOF Fighter Registration =====');
  WriteLn('');

  fighters[1] := TFighter.Create('Kyo Kusanagi',   'Japan Team',        95);
  fighters[2] := TFighter.Create('Iori Yagami',    'Yagami Team',       94);
  fighters[3] := TFighter.Create('Terry Bogard',   'Fatal Fury Team',   90);
  fighters[4] := TFighter.Create('Mai Shiranui',   'Women Fighters Team', 85);
  fighters[5] := TFighter.Create('Leona Heidern',  'Ikari Team',        88);

  WriteLn('');
  WriteLn('===== Fighter Information =====');

  try
    for i := 1 to 5 do begin
      WriteLn('');
      fighters[i].PrintInfo;
    end;

    WriteLn('');
    WriteLn('===== Greeting Messages =====');
    for i := 1 to 5 do begin
      WriteLn('  ', fighters[i].GetGreeting);
    end;

    WriteLn('');
    WriteLn('===== Power Update =====');
    fighters[1].SetPower(99);
    WriteLn('  ', fighters[1].Name, ' power updated to 99.');

    fighters[2].IsActive := False;
    WriteLn('  ', fighters[2].Name, ' has retired.');

    WriteLn('');
    WriteLn('===== Updated Status =====');
    WriteLn('');
    fighters[1].PrintInfo;
    WriteLn('');
    fighters[2].PrintInfo;

  finally
    WriteLn('');
    WriteLn('===== Freeing Instances =====');
    for i := 1 to 5 do begin
      fighters[i].Free;
    end;
  end;

  WriteLn('');
  WriteLn('===== Done =====');
end.
fpc kof_class.pas && ./kof_class
Free Pascal Compiler version ...
Linking ./kof_class
===== KOF Fighter Registration =====

[Created] Kyo Kusanagi has entered the field.
[Created] Iori Yagami has entered the field.
[Created] Terry Bogard has entered the field.
[Created] Mai Shiranui has entered the field.
[Created] Leona Heidern has entered the field.

===== Fighter Information =====

  Name     : Kyo Kusanagi
  Team     : Japan Team
  Power    : 95
  Status   : Active

  Name     : Iori Yagami
  Team     : Yagami Team
  Power    : 94
  Status   : Active

  Name     : Terry Bogard
  Team     : Fatal Fury Team
  Power    : 90
  Status   : Active

  Name     : Mai Shiranui
  Team     : Women Fighters Team
  Power    : 85
  Status   : Active

  Name     : Leona Heidern
  Team     : Ikari Team
  Power    : 88
  Status   : Active

===== Greeting Messages =====
  Kyo Kusanagi (Japan Team) — entering!
  Iori Yagami (Yagami Team) — entering!
  Terry Bogard (Fatal Fury Team) — entering!
  Mai Shiranui (Women Fighters Team) — entering!
  Leona Heidern (Ikari Team) — entering!

===== Power Update =====
  Kyo Kusanagi power updated to 99.
  Iori Yagami has retired.

===== Updated Status =====

  Name     : Kyo Kusanagi
  Team     : Japan Team
  Power    : 99
  Status   : Active

  Name     : Iori Yagami
  Team     : Yagami Team
  Power    : 94
  Status   : Retired

===== Freeing Instances =====
[Freed] Kyo Kusanagi has left the field.
[Freed] Iori Yagami has left the field.
[Freed] Terry Bogard has left the field.
[Freed] Mai Shiranui has left the field.
[Freed] Leona Heidern has left the field.

===== Done =====
kof_simple_class.pas

An example of a simple class without inheritance. TObject is inherited automatically.

{$mode objfpc}
{
  Compile and run:
    fpc kof_simple_class.pas && ./kof_simple_class
}
program kof_simple_class;

type
  TScore = class
  private
    FPlayer : string;
    FPoints : Integer;
  public
    constructor Create(const APlayer: string; APoints: Integer);
    destructor  Destroy; override;
    procedure   Show;
    property    Player : string  read FPlayer;
    property    Points : Integer read FPoints write FPoints;
  end;

constructor TScore.Create(const APlayer: string; APoints: Integer);
begin
  inherited Create;
  FPlayer := APlayer;
  FPoints := APoints;
end;

destructor TScore.Destroy;
begin
  inherited Destroy;
end;

procedure TScore.Show;
begin
  WriteLn(FPlayer, ': ', FPoints, ' pt');
end;

var
  s : TScore;
begin
  s := TScore.Create('Kyo Kusanagi', 9800);
  try
    s.Show;
    s.Points := 10000;
    s.Show;
  finally
    s.Free;
  end;
end.
fpc kof_simple_class.pas && ./kof_simple_class
Free Pascal Compiler version ...
Linking ./kof_simple_class
Kyo Kusanagi: 9800 pt
Kyo Kusanagi: 10000 pt
kof_property_class.pas

An example of using getter/setter properties to control access to fields.

{$mode objfpc}
{
  Compile and run:
    fpc kof_property_class.pas && ./kof_property_class
}
program kof_property_class;

type
  TFighterPower = class
  private
    FName  : string;
    FPower : Integer;
    function  GetPower: Integer;
    procedure SetPower(AValue: Integer);
  public
    constructor Create(const AName: string; APower: Integer);
    destructor  Destroy; override;
    procedure   ShowPower;
    property Name  : string  read FName;
    { getter/setter clamps the value to the range 0..100 }
    property Power : Integer read GetPower write SetPower;
  end;

constructor TFighterPower.Create(const AName: string; APower: Integer);
begin
  inherited Create;
  FName  := AName;
  SetPower(APower);
end;

destructor TFighterPower.Destroy;
begin
  inherited Destroy;
end;

function TFighterPower.GetPower: Integer;
begin
  GetPower := FPower;
end;

procedure TFighterPower.SetPower(AValue: Integer);
begin
  if AValue < 0   then AValue := 0;
  if AValue > 100 then AValue := 100;
  FPower := AValue;
end;

procedure TFighterPower.ShowPower;
begin
  WriteLn(FName, ' — Power: ', FPower);
end;

var
  f : TFighterPower;
begin
  f := TFighterPower.Create('Iori Yagami', 94);
  try
    f.ShowPower;
    f.Power := 150;    { values above 100 are clamped }
    f.ShowPower;
    f.Power := -10;    { values below 0 are clamped }
    f.ShowPower;
  finally
    f.Free;
  end;
end.
fpc kof_property_class.pas && ./kof_property_class
Free Pascal Compiler version ...
Linking ./kof_property_class
Iori Yagami — Power: 94
Iori Yagami — Power: 100
Iori Yagami — Power: 0

Overview

The CLASS declaration in Object Pascal uses private / public / protected sections to control member access, and manages the instance lifecycle with the constructor (Create) and destructor (Destroy). The destructor must be overridden with override, and inherited Destroy must be called to ensure the parent class cleanup runs. For freeing instances, use Free (which includes a nil check) rather than calling Destroy directly. Wrap dynamically created instances in a try...finally block to guarantee that Free is always called even when an exception occurs. For managing classes across multiple files, see UNIT (unit basics). For applying pointers to dynamic data structures, see NEW / DISPOSE (dynamic memory allocation and deallocation).

If you find any errors or copyright issues, please .