Name

Implements Directive

Syntax

Property declaration read Getter implements Interfaces...;

Description

A class can delegate the implementation of one or more interfaces to a property with the implements directive. The property’s Getter must be a field or a simple method (no array or indexed properties allowed). The method can be virtual, but not dynamic or a message handler. The Getter field or method must have a class or interface type. If the property implements more than one interface, separate the interface identifiers with commas.

The listed interfaces must appear in the class declaration.

Tips and Tricks

  • The implements directive is often used to implement COM-style aggregation. The ComObj unit declares the TAggregatedObject class as the base class for the inner object.

  • If the Getter is of class type, you must be careful about the lifetime of the object. Once Delphi casts the object reference to an interface, Delphi’s automatic reference counting manages the object’s lifetime. Once the last interface is out of scope, the object will be freed automatically. The simplest way to manage this situation is for the Getter method to create a new object every time it is called.

  • If the Getter is of class type, you can use method resolution clauses to redirect some of the interface methods to the containing class.

  • If the Getter is of interface type, the returned interface must implement all the listed interfaces. You cannot use method resolution to alter the interfaces.

Example

interface
// In the interface section of a unit, declare the TWizardComponent
// class. The user drops this class on a form to create a wizard,
// that is, an extension to the Delphi IDE using the Open Tools API.
// The wizard must implement the IOTAWizard interface, but you want
// the details of the implementation to be private to the
// implementation section of the unit. Delegating the implementation
// to a property achieves this goal.
type
  TWizardComponent = class(TComponent, IOTAWizard)
  private
    fWizard: IOTAWizard;
    fOnExecute: TNotifyEvent;
    function GetIDString: string;
    procedure SetIDString(const Value: string);
    function GetWizardName: string;
    procedure SetWizardName(const Value: string);
    property Wizard: IOTAWizard read fWizard implements IOTAWizard;
  protected
    procedure Execute; virtual;
  public
    constructor Create(Owner: TComponent); override;
  published
    property IDString: string read GetIDString write SetIDString;
    property WizardName: string read GetWizardName write SetWizardName;
    property OnExecute: TNotifyEvent read fOnExecute write fOnExecute;
  end;

implementation

// The constructor for TWizardComponent creates a TWizard object
// and saves it as the fWizard field. The TWizard object provides
// the actual implementation of the IOTAWizard interface.
type
  TWizard = class(TInterfacedObject, IOTAWIzard)
  private
    fIndex: Integer;
    fOwner: TWizardComponent;
    function GetIDString: string;
    function GetName: string;
    function GetState: TWizardState;
    procedure Execute;
  public
    constructor Create(Owner: TWizardComponent);
    destructor Destroy; override;
  end;

See Also

Class Keyword, Interface Keyword, Property Keyword
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset