Considerate due definizioni di interfaccia ...
IOmniWorkItem = interface ['{3CE2762F-B7A3-4490-BF22-2109C042EAD1}']
function GetData: TOmniValue;
function GetResult: TOmniValue;
function GetUniqueID: int64;
procedure SetResult(const value: TOmniValue);
//
procedure Cancel;
function DetachException: Exception;
function FatalException: Exception;
function IsCanceled: boolean;
function IsExceptional: boolean;
property Data: TOmniValue read GetData;
property Result: TOmniValue read GetResult write SetResult;
property UniqueID: int64 read GetUniqueID;
end;
IOmniWorkItemEx = interface ['{3B48D012-CF1C-4B47-A4A0-3072A9067A3E}']
function GetOnWorkItemDone: TOmniWorkItemDoneDelegate;
function GetOnWorkItemDone_Asy: TOmniWorkItemDoneDelegate;
procedure SetOnWorkItemDone(const Value: TOmniWorkItemDoneDelegate);
procedure SetOnWorkItemDone_Asy(const Value: TOmniWorkItemDoneDelegate);
//
property OnWorkItemDone: TOmniWorkItemDoneDelegate read GetOnWorkItemDone write SetOnWorkItemDone;
property OnWorkItemDone_Asy: TOmniWorkItemDoneDelegate read GetOnWorkItemDone_Asy write SetOnWorkItemDone_Asy;
end;
... quali sono le tue idee per la stesura della dichiarazione di classe che eredita da entrambi?
La mia idea attuale (ma non so se sono felice con questo):
TOmniWorkItem = class(TInterfacedObject, IOmniWorkItem, IOmniWorkItemEx)
strict private
FData : TOmniValue;
FOnWorkItemDone : TOmniWorkItemDoneDelegate;
FOnWorkItemDone_Asy: TOmniWorkItemDoneDelegate;
FResult : TOmniValue;
FUniqueID : int64;
strict protected
procedure FreeException;
protected //IOmniWorkItem
function GetData: TOmniValue;
function GetResult: TOmniValue;
function GetUniqueID: int64;
procedure SetResult(const value: TOmniValue);
protected //IOmniWorkItemEx
function GetOnWorkItemDone: TOmniWorkItemDoneDelegate;
function GetOnWorkItemDone_Asy: TOmniWorkItemDoneDelegate;
procedure SetOnWorkItemDone(const Value: TOmniWorkItemDoneDelegate);
procedure SetOnWorkItemDone_Asy(const Value: TOmniWorkItemDoneDelegate);
public
constructor Create(const data: TOmniValue; uniqueID: int64);
destructor Destroy; override;
public //IOmniWorkItem
procedure Cancel;
function DetachException: Exception;
function FatalException: Exception;
function IsCanceled: boolean;
function IsExceptional: boolean;
property Data: TOmniValue read GetData;
property Result: TOmniValue read GetResult write SetResult;
property UniqueID: int64 read GetUniqueID;
public //IOmniWorkItemEx
property OnWorkItemDone: TOmniWorkItemDoneDelegate read GetOnWorkItemDone write SetOnWorkItemDone;
property OnWorkItemDone_Asy: TOmniWorkItemDoneDelegate read GetOnWorkItemDone_Asy write SetOnWorkItemDone_Asy;
end;
Come notato nelle risposte, la composizione è un buon approccio per questo esempio, ma non sono sicuro che si applichi in tutti i casi. A volte utilizzo l'ereditarietà multipla solo per dividere l'accesso in lettura e scrittura a qualche proprietà in una parte pubblica (in genere di sola lettura) e privata (di solito in sola scrittura). La composizione si applica ancora qui? Non sono proprio sicuro di dover spostare la proprietà in questione dalla classe principale e non sono sicuro che sia il modo corretto di farlo.
Esempio:
// public part of the interface interface
IOmniWorkItemConfig = interface
function OnExecute(const aTask: TOmniBackgroundWorkerDelegate): IOmniWorkItemConfig;
function OnRequestDone(const aTask: TOmniWorkItemDoneDelegate): IOmniWorkItemConfig;
function OnRequestDone_Asy(const aTask: TOmniWorkItemDoneDelegate): IOmniWorkItemConfig;
end;
// private part of the interface
IOmniWorkItemConfigEx = interface ['{42CEC5CB-404F-4868-AE81-6A13AD7E3C6B}']
function GetOnExecute: TOmniBackgroundWorkerDelegate;
function GetOnRequestDone: TOmniWorkItemDoneDelegate;
function GetOnRequestDone_Asy: TOmniWorkItemDoneDelegate;
end;
// implementing class
TOmniWorkItemConfig = class(TInterfacedObject, IOmniWorkItemConfig, IOmniWorkItemConfigEx)
strict private
FOnExecute : TOmniBackgroundWorkerDelegate;
FOnRequestDone : TOmniWorkItemDoneDelegate;
FOnRequestDone_Asy: TOmniWorkItemDoneDelegate;
public
constructor Create(defaults: IOmniWorkItemConfig = nil);
public //IOmniWorkItemConfig
function OnExecute(const aTask: TOmniBackgroundWorkerDelegate): IOmniWorkItemConfig;
function OnRequestDone(const aTask: TOmniWorkItemDoneDelegate): IOmniWorkItemConfig;
function OnRequestDone_Asy(const aTask: TOmniWorkItemDoneDelegate): IOmniWorkItemConfig;
public //IOmniWorkItemConfigEx
function GetOnExecute: TOmniBackgroundWorkerDelegate;
function GetOnRequestDone: TOmniWorkItemDoneDelegate;
function GetOnRequestDone_Asy: TOmniWorkItemDoneDelegate;
end;