Class and Interface Fun

Denis Koroskin 2korden at gmail.com
Sun Jan 25 06:06:50 PST 2009


On Sun, 25 Jan 2009 15:20:19 +0300, Tim M <a at b.com> wrote:

> 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.

No, I don't:

class B : private A, public I
{
}




More information about the Digitalmars-d-learn mailing list