Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2015-10

interface inheritance implementation

12 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

David Emerson

Not sure what subject line to use to summarize what I'm trying to do here, but that is kind of related :)

So I would like to use an interface that inherits from another interface, and ... well rather than describe what I'm trying to do, I think code speaks best.

type
// here is the first interface
i_adder = interface
   ['{01234567-2222-407C-8133-987654FEDCBA}']
   function add (a, b : longint) : longint;
   end;
// this next interface inherits from i_adder, and thus does two things
i_multiplier_and_adder = interface (i_adder)
   ['{A1234567-2222-407C-8133-987654FEDCBA}']
   function multiply (a, b : longint) : longint;
   end;
t_base = TInterfacedObject;
// now an implementing class for i_adder
t_adder = class (t_base, i_adder)
   function add (a, b : longint) : longint;
   end;
// and finally the implementing class for i_multiplier_and_adder
t_multiplier_and_adder = class (tbase, i_multiplier_and_adder)
   f_adder : i_adder;
   function multiply (a, b : longint) : longint;
// THIS PROPERTY DOES NOT WORK:
   property adder : i_adder read f_adder implements i_adder;
   end;

The structure I have is like... I have one instance of t_adder, and I want to have several instances of t_multiplier_and_adder that all use the one instance of t_adder as their hook.

And in my real code, t_adder has 6 methods or so, thus it becomes cumbersome to implement all those in t_multiplier_and_adder, each just calling the function on the t_adder that I'd like to use as a hook.

Do I have to implement all of the individual i_adder methods for t_multiplier_and_adder? Is there no shortcut?

Thanks!
~David.

Graeme Geldenhuys
to David Emerson
David Emerson wrote
// and finally the implementing class for i_multiplier_and_adder t_multiplier_and_adder = class (tbase, i_multiplier_and_adder)

I haven't tried this for a while, but vaguely remember the following. As far as I know Interface inheritance does not work in FPC - or it is not implemented completely in and FPC version. Change your code as follows.

// this next interface inherits from i_adder, and thus does two things
i_multiplier = interface
   ['{A1234567-2222-407C-8133-987654FEDCBA}']
   function multiply (a, b : longint) : longint;
   end;
// and finally the implementing class for i_multiplier and i_adder
t_multiplier_and_adder = class (tbase, i_adder, i_multiplier)
   f_adder : i_adder;
   function multiply (a, b : longint) : longint;
// THIS PROPERTY DOES NOT WORK:
   property adder : i_adder read f_adder implements i_adder;
   end;

In FPC you can't inherit one Interface from another. Define them separately, then mix them together in classes that implement them.

With the above code, you can have one class implement the i_adder interface, and another class that implements the i_multiplier interface. Them create a new t_multiplier_and_adder class that mixes in both interfaces and uses interface delegation - that way you don't have to repeat the actual interface implementations in each class and still get code reuse. I hope this makes sense.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp
Sven Barth
to David Emerson: Not sure what subject line to use to summarize what I'm trying to do here, but that is…
"David Emerson" wrote
Do I have to implement all of the individual i_adder methods for

t_multiplier_and_adder? Is there no shortcut?

AFAIK you can only delegate interfaces that are part of the class' declaration, in your case i_multiplier_and_adder, but not inherited interfaces, in your case i_adder. I don't know whether we "copied" that restriction from Delphi or if it is a shortcoming of our incomplete delegation implementation (e.g. in Delphi you can delegate to properties with a class type as well).

Regards,
Sven

Graeme Geldenhuys
to Sven Barth
Sven Barth wrote
AFAIK you can only delegate interfaces that are part of the class' declaration, in your case i_multiplier_and_adder, but not inherited interfaces, in your case i_adder.

That is exactly what I meant when I said "interface inheritance is not fully implemented in any FPC". I the last week or two read a conversation (can't remember if it was Laz Forums or Google+) where a Delphi developer did this, but couldn't get that same code to work under FPC.

FPC compiler doesn't give any errors - but doesn't support the functionality either. I haven't personally tested, but from the conversation I read, Delphi allows that. I don't have time to test this right now under Delphi, but will have a look later tonight.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp
Graeme Geldenhuys
to Graeme Geldenhuys
Graeme Geldenhuys wrote
I the last week or two read a conversation (can't remember if it was Laz Forums or Google+) where a Delphi developer did this, but couldn't get that same code to work under FPC.

Scratch that.... I'll rather try and find the exact article/blog I read to make double sure what was and what wasn't working in FPC.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp
Graeme Geldenhuys
to David Emerson: Not sure what subject line to use to summarize what I'm trying to do here, but that is…
David Emerson wrote
So I would like to use an interface that inherits from another interface, and ... well rather than describe what I'm trying to do, I think code speaks best.

Attached is a working example, tested under Delphi 7 and FPC 2.6.4. It is slightly different to your example, but might give you an idea of how to solve your issue.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp
Sven Barth
to Graeme Geldenhuys: Scratch that.... I'll rather try and find the exact article/blog I read to make double…

Am 12.10.2015 15:44 schrieb "Graeme Geldenhuys" <

Show quoted text 12 lines
: On 2015-10-12 14:17, Graeme Geldenhuys wrote: > I the last week or two read a > conversation (can't remember if it was Laz Forums or Google+) where a > Delphi developer did this, but couldn't get that same code to work under > FPC. Scratch that.... I'll rather try and find the exact article/blog I read to make double sure what was and what wasn't working in FPC.

Would be nice if you'd find it. We know of some discrepancies with the delegation implementation (inheritance alone should be compatible already), but if there are some more it's good to know them. This way they can be fixed once someone tackles the delegation support.

Regards,
Sven

Graeme Geldenhuys
to Sven Barth
Sven Barth wrote
Would be nice if you'd find it.

I found it, but the point is moot (just like my recent post about Interface documentation bug). It's Blue Monday for me today. :-[

http://stackoverflow.com/questions/31626388/is-multiple-interface-inheritance-not-supported-by-lazarus

Multiple Inheritance of interfaces are not allowed in the following way (syntax) - for both Delphi and FPC:

type
  ISegment = interface(IRenderable, IMover)
  end;

I got a bit confused regarding the StackOverflow post, and what the original author in this thread meant. Sorry for the noise.

Regards,
- Graeme -

Unknown author
to Graeme Geldenhuys
Graeme Geldenhuys wrote 5 lines
On 2015-10-12 16:18, Sven Barth wrote: > Would be nice if you'd find it. I found it, but the point is moot (just like my recent post about Interface documentation bug). It's Blue Monday for me today. :-[

[...]

I got a bit confused regarding the StackOverflow post, and what the original author in this thread meant. Sorry for the noise.

sounds like it is about time for beer-o'clock, eh? ;)

NOTE: No off-list assistance is given without prior approval. *Please keep mailing list traffic on the list* unless private contact is specifically requested and granted.
David Emerson
to Graeme Geldenhuys: I haven't tried this for a while, but vaguely remember the following. As far as I know…
Graeme Geldenhuys wrote
t_multiplier_and_adder = class (tbase, i_adder, i_multiplier)

Thanks for this recommendation-- the problem is that I have a list whose elements are each i_multiplier_and_adder, and I want to be able to take an element of that list and have the full capability. So separating i_multiplier from i_adder creates a different problem.

The other recommendation was essentially to make a proper delegate that is not an instance of the ancestor interface. But that doesn't work for me, because -- as I wrote initially -- I have one instance of the ancestor, and multiple instances of the child that need to work differently for their own stuff but all call on the one singular ancestor instance for its interface.

So far I have not figured out how to typecast an interface into its implementing class, which would be an alternate solution for my particular situation.

For the time being, I guess there's no shortcut - I just have to implement all of the i_adder methods in i_multiplier_and_adder, and have them call the same method in the "hook" which is unable to be a delegate.

Thanks for your responses, all!

~David.

Sven Barth
to David Emerson
"David Emerson" wrote
So far I have not figured out how to typecast an interface into its

implementing class, which would be an alternate solution for my particular situation.

As long as it's a COM-style interface you can use "intf as classtype". Be aware though that you can get problems with reference counting as the class instance won't be subject to the reference counting like the interface instance is.

Regards,
Sven