Board index » delphi » Re: Implementing an interface the same way in different classes...

Re: Implementing an interface the same way in different classes...


2003-08-05 10:00:58 PM
delphi131
Use the implements keyword (look in the help for this one) and an internal
object that implements the interface.
Be careful about ref counting - you want the internal object to delegate
addref and release to the container!
Bryan
"Harry Ragland" <XXXX@XXXXX.COM>writes
Quote
Is there a "best practice" for implementing an interface the same way in
different classes? (without all inheriting from the same base class)

Thanks,

Harry Ragland
QS Technologies, Inc.



 
 

Re: Implementing an interface the same way in different classes...

Harry Ragland writes:
| Is there a "best practice" for implementing an interface the same way in
| different classes? (without all inheriting from the same base class)
Yes, create a separate class that implements the interface and instantiate
it in the various classes into a private variable that is referenced by a
property that implements the interface.
IUsefulInterface = interface
function GetIt: Integer;
end;
TUsefulClass = class(TInterfacedObject, IUsefulInterface)
protected
function GetIt: Integer;
end;
TImplementingClass = class(TSomething, IUsefulInterface)
private
fUseful: IUsefulInterface;
property Useful: IUsefulInterface
read fUseful
implements IUsefulInterface;
protected
.....
public
constructor Create;
end;
constructor Create;
begin
inherited Create;
fUseful := TUsefulClass.Create;
end;
Joanna
 

Re: Implementing an interface the same way in different classes...

Bryan Crotaz writes:
| Be careful about ref counting - you want the internal object to delegate
| addref and release to the container!
only if the two refer to each other mutually.
Joanna
 

Re: Implementing an interface the same way in different classes...

Thanks.
I looked up Implementing interfaces by delegation in the Delphi 7 help and a note
in there says:
Note
The class you use to implement the delegated interface should derive from
TAggregatedObject.
Would that be the TSomething below?
--
Thanks,
Harry Ragland
QS Technologies, Inc.
"Joanna Carter" <XXXX@XXXXX.COM>writes
Quote
Harry Ragland writes:

| Is there a "best practice" for implementing an interface the same way in
| different classes? (without all inheriting from the same base class)

Yes, create a separate class that implements the interface and instantiate
it in the various classes into a private variable that is referenced by a
property that implements the interface.

IUsefulInterface = interface
function GetIt: Integer;
end;

TUsefulClass = class(TInterfacedObject, IUsefulInterface)
protected
function GetIt: Integer;
end;

TImplementingClass = class(TSomething, IUsefulInterface)
private
fUseful: IUsefulInterface;
property Useful: IUsefulInterface
read fUseful
implements IUsefulInterface;
protected
.....
public
constructor Create;
end;

constructor Create;
begin
inherited Create;
fUseful := TUsefulClass.Create;
end;

Joanna

--
Joanna Carter
Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker


 

Re: Implementing an interface the same way in different classes...

Joanna Carter writes:
[snip]
Quote
TImplementingClass = class(TSomething, IUsefulInterface)
private
fUseful: IUsefulInterface;
property Useful: IUsefulInterface
read fUseful
implements IUsefulInterface;
Aha: now is you using my TSomething class idea. ;)
Solerman
 

Re: Implementing an interface the same way in different classes...

"Joanna Carter" <XXXX@XXXXX.COM>writes
Quote
Bryan Crotaz writes:

| Be careful about ref counting - you want the internal object to delegate
| addref and release to the container!

only if the two refer to each other mutually.
No - you're thinking of weak pointers. I mean that you want the lifetime of
the implementer to be tied to the lifetime of the container. You don't want
someone to get an interface as IInternalThingy, release it and have your
internal object destroyed. At the same time, you probably don't want the
container to be able to be destroyed while someone has a pointer to the
internal object.
Bryan
 

Re: Implementing an interface the same way in different classes...

"Harry Ragland" <XXXX@XXXXX.COM>writes
Quote
Thanks.

I looked up Implementing interfaces by delegation in the Delphi 7 help and a
note
in there says:

Note
The class you use to implement the delegated interface should derive from
TAggregatedObject.

Would that be the TSomething below?
No. The TUsefulObject should descend from TAggregatedObject. Look at the
source for TAggregatedObject and my post above, and you will see what I meant.
Bryan
Quote
Thanks,

Harry Ragland
QS Technologies, Inc.


"Joanna Carter" <XXXX@XXXXX.COM>writes
news:3f2fbe47$XXXX@XXXXX.COM...
>Harry Ragland writes:
>
>| Is there a "best practice" for implementing an interface the same way
in
>| different classes? (without all inheriting from the same base class)
>
>Yes, create a separate class that implements the interface and
instantiate
>it in the various classes into a private variable that is referenced by
a
>property that implements the interface.
>
>IUsefulInterface = interface
>function GetIt: Integer;
>end;
>
>TUsefulClass = class(TInterfacedObject, IUsefulInterface)
>protected
>function GetIt: Integer;
>end;
>
>TImplementingClass = class(TSomething, IUsefulInterface)
>private
>fUseful: IUsefulInterface;
>property Useful: IUsefulInterface
>read fUseful
>implements IUsefulInterface;
>protected
>.....
>public
>constructor Create;
>end;
>
>constructor Create;
>begin
>inherited Create;
>fUseful := TUsefulClass.Create;
>end;
>
>Joanna
>
>--
>Joanna Carter
>Consultant Software Engineer
>TeamBUG support for UK-BUG
>TeamMM support for ModelMaker
>
>


 

Re: Implementing an interface the same way in different classes...

Bryan Crotaz writes:
| No. The TUsefulObject should descend from TAggregatedObject. Look at the
| source for TAggregatedObject and my post above, and you will see what I
| meant.
TAggregatedObject is not a good idea if you use an interface reference for
the private field. It will only work if you use an object reference,
otherwise the delegate object never gets released.
Joanna
 

Re: Implementing an interface the same way in different classes...

"not a good idea" is the understatement of the year...
ALWAYS use object references for implementor objects. Or write your own
version of Aggregated Object like we did that has a weak pointer to the
controller.
Bryan
"Joanna Carter" <XXXX@XXXXX.COM>writes
Quote
Bryan Crotaz writes:

| No. The TUsefulObject should descend from TAggregatedObject. Look at
the
| source for TAggregatedObject and my post above, and you will see what I
| meant.

TAggregatedObject is not a good idea if you use an interface reference for
the private field. It will only work if you use an object reference,
otherwise the delegate object never gets released.

Joanna

--
Joanna Carter
Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker


 

Re: Implementing an interface the same way in different classes...

Thanks for all of the info.
Can you recommend a document that explains these concepts?
Thanks,
Harry Ragland
QS Technologies, Inc.
 

Re: Implementing an interface the same way in different classes...

Just as I thought I was putting it all together, I looked at Delegating to a
class-type property in Delphi 7 Help and found this:
TMyClass = class(TInterfacedObject, IMyInterface)
FMyImplClass: TMyImplClass;
property MyImplClass: TMyImplClass read FMyImplClass implements
IMyInterface;
procedure IMyInterface.P1 = MyP1;
procedure MyP1;
end;
It is a TInterfacedObject that uses an object reference. I thought I
understood from your posts that:
TInterfacedObject goes with interface reference
TAggregatedObject goes with object reference
Is the Delphi 7 Help being less than helpful here?
Thanks,
Harry Ragland
QS Technologies, Inc.
"Bryan Crotaz" <bryan@%nospam%ivisionsystems.com>writes
Quote
"not a good idea" is the understatement of the year...

ALWAYS use object references for implementor objects. Or write your own
version of Aggregated Object like we did that has a weak pointer to the
controller.

Bryan


"Joanna Carter" <XXXX@XXXXX.COM>writes
news:3f30b88f$XXXX@XXXXX.COM...
>Bryan Crotaz writes:
>
>| No. The TUsefulObject should descend from TAggregatedObject. Look at
the
>| source for TAggregatedObject and my post above, and you will see what I
>| meant.
>
>TAggregatedObject is not a good idea if you use an interface reference
for
>the private field. It will only work if you use an object reference,
>otherwise the delegate object never gets released.
>
>Joanna
>
>--
>Joanna Carter
>Consultant Software Engineer
>TeamBUG support for UK-BUG
>TeamMM support for ModelMaker
>
>