Overview

Metaclasses

treating classes as first-class values

Source Code

<?pas
// Metaclasses: treating classes as first-class values

type
  TShape = class
    constructor Create; virtual;
    begin
      PrintLn('Creating ' + ClassName);
    end;
    function Area: Float; virtual; abstract;
  end;

type
  TCircle = class(TShape)
    Radius: Float;
    constructor Create; override;
    begin
      inherited;
      Radius := 1.0;
    end;
    function Area: Float; override;
    begin
      Result := Pi * Sqr(Radius);
    end;
  end;

type
  TSquare = class(TShape)
    Side: Float;
    constructor Create; override;
    begin
      inherited;
      Side := 1.0;
    end;
    function Area: Float; override;
    begin
      Result := Sqr(Side);
    end;
  end;

// Metaclass type declaration
type
  TShapeClass = class of TShape;

// Factory function using metaclass
function CreateShape(ShapeClass: TShapeClass): TShape;
begin
  Result := ShapeClass.Create;  // Virtual constructor call
end;

// Registry pattern
var registry: array[String] of TShapeClass;
registry['circle'] := TCircle;
registry['square'] := TSquare;

// Dynamic instantiation from string
var shapeName := 'circle';
if shapeName in registry then begin
  var shape := CreateShape(registry[shapeName]);
  PrintLn('Area: ' + shape.Area.ToString(2));
end;

// Class identity checks
var cls: TShapeClass := TSquare;
// We can use the metaclass to create an instance
var instance := cls.Create;
PrintLn('Created instance of ' + instance.ClassName);
?>

Result

Creating TCircle
Area: 3.14
Creating TSquare
Created instance of TSquare
On this page