SmartPascal
Class
Keyword
Starts the declaration of a type of object class
  1. type Name = {packed} class
       Definitions...      
       {class function|procedure ...}
     end;
 
  2. type Name = class(BaseClass);
 
  3. type Name = class;
 
  4. type Name = {packed} class(BaseClass)
       Class definition...
     end;
 
  5. type Name = {packed} class(BaseClass {,Interfaces})
       Class definition...
     end;
 
  6. type MetaClassName = class of class type;
Description
The Class keyword is the central part of Object Oriented code. It starts the definition of literally a 'class' of object types.
 
This definition contains so-called 'members' - data and methods (subroutines). When an object of the class is created, it is a stand alone item - you can access the data and methods of the object independently of any other object. It is like a Delphi record, but with active components - methods.
 
These elements are defined in the class type definition. The method elements are implemented in the implementation section of the Unit.
 
A class declaration has this typical basic layout :
 
type
  className = class(BaseClass)
  private
    // Data/method defs local to this Unit
  protected
    // Data/method defs local to this class + descendants
  public
    // Data/method defs usable with all objects of this class
  published
    // Externally interrogatable public definitions
end;

 
Parameters can be passed when creating an object instance of a class. These are passed to the Constructor method of the class. The word constructor is used instead of function or method. You may have a number of constructors for different parameter sets. These are supplied with the overload; keyword after the end of the constructor definition.
 
Normally, the constructor method name is Create.
 
See the code for an example.
 
When an object is destroyed, the Destructor method is called. You can use this to take special action before the object storage is reclaimed.
 
Normally, the destructor method name is Destroy.
 

 
There are a number of uses of the word Class:
 
1. A class definition based on the TObject class by default. All classes must be based on another class, with TObject being the default, highest level class. TObject provides rudimentry functionality - you would normally define all of the data and methods yourself, and use none from TObject.
 
Within the definitions of a Class, you can prefix function or procedure definitions with the Class keyword. This allows the subroutine to be called from the Class itself in addition to an object instance of the class. Because a class is not a real object, it has no storage allocated to data. So a Class subroutine must operate without reference to internal class data.
 
2. Class definition based on a specified class but with no local additions or changes. You have a new class that acts identically to the BaseClass
 
3. Forward class declaration. It allows all classes in a Unit to be listed at the start of the type section. So this is a matter of convenience rather than anything else.
 
4. Class definition based on a specified class. As 1 above, but you can specify which class you are basing your new class on. Your class will again be a mixture of ancestor and local declarations.
 
5. A class can contain implementations of externally predefined interfaces.
 
6. A metaclass reference allows a variable to be used to reference a class rather than an object.
Notes
The optional packed keyword tells Delphi to minimise storage taken by the class. It stops aligning data on 2, 4 or 8 byte boundaries, normally done for performance reasons.
Related commands
Constructor Defines the method used to create an object from a class
Interface Used for Unit external definitions, and as a Class skeleton
Object Allows a subroutine data type to refer to an object method
Private Starts the section of private data and methods in a class
Property Defines controlled access to class fields
Protected Starts a section of class private data accesible to sub-classes
Public Starts an externally accessible section of a class
Published Starts a published externally accessible section of a class
TObject The base class type that is ancestor to all other classes
Virtual Allows a class method to be overriden in derived classes
Dynamic Allows a class method to be overriden in derived classes
 
Example code : A Unit with 2 class definitions and code that uses both
// Full Unit code.
// -----------------------------------------------------------
// You must store this code in a unit called Unit1 with a form
// called Form1 that has an OnCreate event called FormCreate.

unit Unit1;

interface

uses
  SysUtils, Forms, Dialogs;

type
  // Define the classes in this Unit at the very start for clarity
  TForm1 = Class;          // This is a forward class definition

  TFruit = Class(TObject)  // This is an actual class definition :
    // Internal class field definitions - only accessible in this unit
    private
      isRound  : Boolean;
      length   : single;
      width    : single;
      diameter : single;
    // Fields and methods only accessible by this class and descendants
    protected
    // Externally accessible fields and methods
    public
      // 2 constructors - one for round fruit, the other long fruit
      constructor Create(diameter : single);               overload;
      constructor Create(length : single; width : single); overload;
    // Externally accessible and inspectable fields and methods
    published
      // Note that properties must use different names to local defs
      property round : Boolean
        read   isRound;
      property len   : single
        read   length;
      property wide  : single
        read   width;
      property diam  : single
        read   diameter;
  end;                    // End of the TFruit class definition

  // The actual TForm1 class is now defined
  TForm1 = Class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure ShowFruit(fruit : TFruit);
  private
    // No local data
  public
    // Uses just the TForm ancestor class public definitions
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// Create a round fruit object
constructor TFruit.Create(diameter: single);
begin
  // Indicate that we have a round fruit, and set its size
  isRound       := true;
  self.diameter := diameter;
end;

// Create a long fruit object
constructor TFruit.Create(length, width: single);
begin
  // Indicate that we have a long fruit, and set its size
  isRound     := false;
  self.length := length;
  self.width  := width;
end;

// Form object - action taken when the form is created
procedure TForm1.FormCreate(Sender: TObject);
var
  apple, banana : TFruit;
begin
  // Let us create our fruit objects
  apple  := TFruit.Create(3.5);
  banana := TFruit.Create(7.0, 1.75);

  // Show details about our fruits
  ShowFruit(apple);
  ShowFruit(banana);
end;

// Show what the characteristics of our fruit are
procedure TForm1.ShowFruit(fruit: TFruit);
begin
  if fruit.round
  then ShowMessage('We have a round fruit, with diam = '+
                   FloatToStr(fruit.diam))
  else
  begin
    ShowMessage('We have a long fruit');
    ShowMessage('    it has length = '+FloatToStr(fruit.len));
    ShowMessage('    it has width  = '+FloatToStr(fruit.wide));
  end;
end;

end.
   We have a round fruit with diam = 3.5
   We have a long fruit
       it has a length = 7
       it has a width = 1.75