treating classes as first-class values
<?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);
?>
Creating TCircle Area: 3.14 Creating TSquare Created instance of TSquare