Class and Interface Fun

John Reimer terminal.node at gmail.com
Sun Jan 25 14:31:59 PST 2009


Hello tim,

> On Mon, 26 Jan 2009 04:58:57 +1300, John Reimer
> <terminal.node at gmail.com>  wrote:
> 
>> Hello tim,
>> 
>>> On Mon, 26 Jan 2009 01:14:10 +1300, Denis Koroskin
>>> <2korden at gmail.com> wrote:
>>> 
>>>> On Sun, 25 Jan 2009 15:06:23 +0300, Tim M <a at b.com> wrote:
>>>> 
>>>>> On Mon, 26 Jan 2009 00:48:21 +1300, Tim M <a at b.com> wrote:
>>>>> 
>>>>>> On Mon, 26 Jan 2009 00:18:28 +1300, Denis Koroskin
>>>>>> <2korden at gmail.com>  wrote:
>>>>>> 
>>>>>>> On Sun, 25 Jan 2009 08:38:18 +0300, Tim M <a at b.com> wrote:
>>>>>>> 
>>>>>>>> On Sun, 25 Jan 2009 17:56:03 +1300, John Reimer
>>>>>>>> <terminal.node at gmail.com> wrote:
>>>>>>>>> Hello tim,
>>>>>>>>> 
>>>>>>>>>> On Sun, 25 Jan 2009 16:43:55 +1300, John Reimer
>>>>>>>>>> <terminal.node at gmail.com>  wrote:
>>>>>>>>>>> With this code:
>>>>>>>>>>> --------------------------------
>>>>>>>>>>> module test5;
>>>>>>>>>>> interface I
>>>>>>>>>>> {
>>>>>>>>>>> void foo();
>>>>>>>>>>> }
>>>>>>>>>>> class A : I {
>>>>>>>>>>> void foo() { }
>>>>>>>>>>> }
>>>>>>>>>>> class B : A, I
>>>>>>>>>>> {
>>>>>>>>>>> alias A.foo foo;
>>>>>>>>>>> }
>>>>>>>>>>> void main()
>>>>>>>>>>> {
>>>>>>>>>>> }
>>>>>>>>>>> --------------------------------
>>>>>>>>>>> I get this error:
>>>>>>>>>>> --------------------------------
>>>>>>>>>>> class test5.B interface function I.foo is not implemented
>>>>>>>>>>> --------------------------------
>>>>>>>>>>> Does this make sense?  I mean, shouldn't the explicit reuse
>>>>>>>>>>> of
>>>>>>>>>>> A.foo
>>>>>>>>>>> in  B be sufficient indication to the compiler that B is
>>>>>>>>>>> satisfying
>>>>>>>>>>> the  contract I?   I'm hoping to make use of such subtleties
>>>>>>>>>>> in
>>>>>>>>>>> some
>>>>>>>>>>> code,  but first I have to understand the reasoning behind
>>>>>>>>>>> this.
>>>>>>>>>>> :)
>>>>>>>>>>> Note that this works if I remove the interface I from B's
>>>>>>>>>>> declaration
>>>>>>>>>>> --  ie "class B: A" -- since, in the D language, B is not
>>>>>>>>>>> required to
>>>>>>>>>>> fulfull A's interface contract even though it inherits from
>>>>>>>>>>> it.
>>>>>>>>>>> -JJR
>>>>>>>>>> It look like the real bug is re-allowing B to implement
>>>>>>>>>> interface I
>>>>>>>>>> but
>>>>>>>>>> sometimes bug do get reported differently. Why don't you
>>>>>>>>>> remove
>>>>>>>>>> I
>>>>>>>>>> from
>>>>>>>>>> B's
>>>>>>>>>> declaration like you said that works. It actually says here
>>>>>>>>>> http://www.digitalmars.com/d/1.0/interface.html "Classes
>>>>>>>>>> cannot
>>>>>>>>>> derive
>>>>>>>>>> from an interface multiple times."
>>>>>>>>> Yes, please check the link again (further down the page).    D
>>>>>>>>> allows you to reimplement the interface as long as class B
>>>>>>>>> provides  a new implementation:
>>>>>>>>> "A reimplemented interface must implement all the interface
>>>>>>>>> functions, it does not inherit from a super class"...
>>>>>>>>> That probably could be stated a little more clearly, but
>>>>>>>>> that's
>>>>>>>>> what it says.  As for why I'm doing it, I assure you that
>>>>>>>>> there's a  very specific reason why I'm trying this: it is a
>>>>>>>>> possible  interfacing mechansim for ported software of a much
>>>>>>>>> more  complicated nature than this simple reduction; I reduced
>>>>>>>>> it to this  in order to try to understand potential
>>>>>>>>> iteractions
>>>>>>>>> between class  and interface layers.  The question here was to
>>>>>>>>> figure out the  reasoning behind the language design,  not
>>>>>>>>> necessarily whether I  should be doing it or not. ;-)
>>>>>>>>> -JJR
>>>>>>>> This works btw:
>>>>>>>> module test;
>>>>>>>> interface I
>>>>>>>> {
>>>>>>>> void foo();
>>>>>>>> }
>>>>>>>> class A : I {
>>>>>>>> void foo() { }
>>>>>>>> }
>>>>>>>> class B : A,I
>>>>>>>> {
>>>>>>>> void foo() { A.foo(); }
>>>>>>>> }
>>>>>>>> void main()
>>>>>>>> {
>>>>>>>> }
>>>>>>> It is too verbose and makes twice an overhead. I'd like to avoid
>>>>>>> this
>>>>>>> solution.
>>>>>>> In fact, I believe that class B : A, I {} should just work.
>>>>>> why? I think it is perfect how it is. You can either leave A as
>>>>>> the class that implements I and B would implement it through
>>>>>> inheritance  or you can to re implement I define all new
>>>>>> implementations and put in  return super.foo(); where needed. It
>>>>>> is also possible to reimplement  one interface function without
>>>>>> re implementing the whole interface.
>>>>>> 
>>>>> If you are really needing to write least code you could also do
>>>>> something like this but not very nice to read:
>>>>> module test;
>>>>> template II(char[] func)
>>>>> {
>>>>> const char[] II = "typeof(super." ~ func ~ "())" ~ " " ~ func ~
>>>>> "() {  return super." ~ func ~ "(); }" ;
>>>>> }
>>>>> interface I
>>>>> {
>>>>> void foo();
>>>>> int bar();
>>>>> }
>>>>> class A : I
>>>>> {
>>>>> void foo() { }
>>>>> int bar() { return 1; }
>>>>> }
>>>>> class B : A,I
>>>>> {
>>>>> //void foo() { return super.foo(); }
>>>>> mixin(II!("foo"));
>>>>> mixin(II!("bar"));
>>>>> }
>>>>> void main()
>>>>> {
>>>>> }
>>>> Not only I want to write less, I want my code be cleaner and run
>>>> faster.
>>>> 
>>>>> why? I think it is perfect how it is. You can either leave A as
>>>>> the class that implements I and B would implement it through
>>>>> inheritance or  you can to re implement I define all new
>>>>> implementations and put in  return super.foo(); where needed. It
>>>>> is also possible to reimplement  one interface function without re
>>>>> implementing the whole interface.
>>>>> 
>>>> That what /my/ solution do.
>>>> class B : A, I {}
>>>> is *absolutely* same as
>>>> class B : A, I
>>>> {
>>>> override void foo() { super.foo(); }
>>>> override int bar() { return super.bar(); }
>>>> }
>>>> Except that when you call B.foo, there is no damn double virtual
>>>> function call.
>>>> B inherits all the functions from A implicitly. You stil may
>>>> override
>>>> any of the I interface functions if need be:
>>>> class B : A, I
>>>> {
>>>> override void foo() { ... }
>>>> // int bar() is inherited from A
>>>> }
>>>> Having B explicitly override all the base class virtual functions
>>>> and
>>>> forward them to A implementation just to make compiler happy is
>>>> unintuitive and plain dumb to me.
>>>> C# allows that and I see absolutely no reason why D doesn't.
>>> I think you are missing somethinghere. Change the B definition from:
>>> class B : A, I
>>> to just:
>>> class B : A
>>> then interfaces become impicit.
>> What do you mean?  In your example above, B does not have to
>> implement  the interface I of A.  What do you mean by "interfaces
>> become implicit"?
>> 
>> -JJR
>> 
> I mean it will still have the foo function and you dont have to put
> anything on B to make it work:
> 
> module test;
> 
> interface I
> {
> void foo();
> }
> class A : I
> {
> void foo() { }
> }
> class B : A
> {
> }
> 
> void main()
> {
> B b = new B;
> b.foo(); //this works
> }


Oops.  You are right.  I missed that.  I got this mixed up with overload 
rules.  Thanks.  


"alias" is used in the subclass to /overload/ a method with super class ones. 
 


Unfortunately, because my assumptions were askew, I've got to retrace my 
steps.  It's good this stayed in learn, afterall. :D


Still, on the case of interface re-implementation, it would be nice if using 
the "alias" would work as I previously specified, though there are certainly 
workarounds available, if necessary.


-JJR




More information about the Digitalmars-d-learn mailing list