Class and Interface Fun

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


On Sun, 25 Jan 2009 17:06:50 +0300, Denis Koroskin <2korden at gmail.com> wrote:

> 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
> {
> }
>
>

Other example:

interface IOStream : InputStream, OutputStream
{
}

class A : InputStream
{
   // implement InputStream
}

class B : A, IOStream
{
   // implement OutputStream interface *only*
}

You can't define B like this: class B : A, OutputStream { ... } because this way it won't be castable to IOStream.



More information about the Digitalmars-d-learn mailing list