Class and Interface Fun

Denis Koroskin 2korden at gmail.com
Sun Jan 25 04:14:10 PST 2009


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.



More information about the Digitalmars-d-learn mailing list