Implements Directive
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.
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.
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;