Thread overview
Bug or Feature?
Jun 13, 2006
leoandru
Jun 13, 2006
Frits van Bommel
Jun 13, 2006
leoandru
Jun 13, 2006
leoandru
Jun 14, 2006
Max Samuha
Jun 14, 2006
leoandru
Jun 14, 2006
Max Samuha
Jun 13, 2006
Sjoerd van Leent
June 13, 2006
I started coding in D a few days now but I ran into a few problems, I wasn't sure if these were bugs so I didnt make a bug report. the problem is with interface inheritance and method signatures It doesn't ssem to work as expected and I don't see any documentation saying otherwise.

interface A
{
void method();
}


interface B : A
{
void method(int a);
}


class Foo : B
{
}


B ref = new Foo();
ref.method();   //doesnt compile, requires an argument.

This works if the method name in interface B is different from A, Im able to call method from interface. Am I doing something wrong? I expected this to work. I'm using dmd 0.160 compile on winxp. Thanks for any help/replies!


June 13, 2006
leoandru@gmail.com wrote:
> I started coding in D a few days now but I ran into a few problems, I wasn't
> sure if these were bugs so I didnt make a bug report. the problem is with
> interface inheritance and method signatures It doesn't ssem to work as expected
> and I don't see any documentation saying otherwise.
> 
> interface A
> {
> void method();
> }
> 
> 
> interface B : A
> {

alias A.method method;

> void method(int a);
> }
> 
> 
> class Foo : B
> {

void method()      { writefln("method()"); }
void method(int a) { writefln("method(", a, ")"); }

> }
> 
> 

void main()
{
    B ref = new Foo();
    ref.method();
    ref.method(1);
}
/*
> B ref = new Foo();
> ref.method();   //doesnt compile, requires an argument.
*/
> 
> This works if the method name in interface B is different from A, Im able to
> call method from interface. Am I doing something wrong? I expected this to work.
> I'm using dmd 0.160 compile on winxp. Thanks for any help/replies!

The new method in B hides the one in A.
With the above modifications it should compile and work.

The use of 'alias' here and why it's necessary is explained in (among other places) http://www.digitalmars.com/d/function.html, under "Function Inheritance and Overriding":

<quote>
However, when doing overload resolution, the functions in the base class are not considered:

[...]

To consider the base class's functions in the overload resolution process, use an /AliasDeclaration/:

[...]
</quote>
June 13, 2006
leoandru@gmail.com schreef:
> I started coding in D a few days now but I ran into a few problems, I wasn't
> sure if these were bugs so I didnt make a bug report. the problem is with
> interface inheritance and method signatures It doesn't ssem to work as expected
> and I don't see any documentation saying otherwise.
> 
> interface A
> {
> void method();
> }
> 
> 
> interface B : A
> {
> void method(int a);
> }
> 
> 
> class Foo : B
> {
> }
> 
> 
> B ref = new Foo();
> ref.method();   //doesnt compile, requires an argument.
> 
> This works if the method name in interface B is different from A, Im able to
> call method from interface. Am I doing something wrong? I expected this to work.
> I'm using dmd 0.160 compile on winxp. Thanks for any help/replies!
> 
> 

Well it isn't suppose to compile, this file, since the interface methods need to be implemented anyway. Let's see the problem:

module test;

interface A {
	void method();
}

interface B : A {
	void method(int a);
}

class Foo : B {
}

void main() {
	Foo foo = new Foo();
	foo.method();
}

This generates the problem you where talking about. Let's first implement the contract of interface A:

class Foo : B {
	void method() {
		int i = 5 + 8;
	}
}

Now another error is going to pop up, which is yielding that the method from interface B is not implemented. Exchange it with the contract of interface B, not implementing interface A:

class Foo : B {
	void method(int a) {
		int i = 5 + a;
	}
}

void main() {
	Foo foo = new Foo();
	foo.method(8);
}

And now we get again that function B.method is not implemented. This is correct behaviour, since interfaces only know about contracts. So interface B, by inheriting interface A makes function A.method also one of the function B.method items.

The complete new source:

module test;

interface A {
	void method();
}

interface B : A{
	void method(int a);
}

class Foo : B {
	void method() {
		int i = 5 + 8;
	}
	
	void method(int a) {
		int i = 5 + a;
	}
}

void main() {
	Foo foo = new Foo();
	foo.method(8);
	foo.method();
}

The compiler warning in the beginning has just to do with compile order.  Anyway, both methods should be implemented, so that's good. How the compiler implements the order of testing I can't say, this is for Walter to come up with.

Regards,
Sjoerd
June 13, 2006
In article <e6n4rl$kkm$1@digitaldaemon.com>, Frits van Bommel says...
>
>leoandru@gmail.com wrote:
>> I started coding in D a few days now but I ran into a few problems, I wasn't sure if these were bugs so I didnt make a bug report. the problem is with interface inheritance and method signatures It doesn't ssem to work as expected and I don't see any documentation saying otherwise.
>> 
>> interface A
>> {
>> void method();
>> }
>> 
>> 
>> interface B : A
>> {
>
>alias A.method method;
>
>> void method(int a);
>> }
>> 
>> 
>> class Foo : B
>> {
>
>void method()      { writefln("method()"); }
>void method(int a) { writefln("method(", a, ")"); }
>
>> }
>> 
>> 
>
>void main()
>{
>     B ref = new Foo();
>     ref.method();
>     ref.method(1);
>}
>/*
>> B ref = new Foo();
>> ref.method();   //doesnt compile, requires an argument.
>*/
>> 
>> This works if the method name in interface B is different from A, Im able to call method from interface. Am I doing something wrong? I expected this to work. I'm using dmd 0.160 compile on winxp. Thanks for any help/replies!
>
>The new method in B hides the one in A.
>With the above modifications it should compile and work.
>
>The use of 'alias' here and why it's necessary is explained in (among other places) http://www.digitalmars.com/d/function.html, under "Function Inheritance and Overriding":
>
><quote>
>However, when doing overload resolution, the functions in the base class
>are not considered:
>
>[...]
>
>To consider the base class's functions in the overload resolution process, use an /AliasDeclaration/:
>
>[...]
></quote>


Ok I see then that is just like writing the method signature of Interface A into
B. Is that really necessary? at least I expected interfaces to behave the way
they do in java or C#. hrm not what I expected, after all interface B is not an
override but rather and overloaded version. I wonder what was the reason behind
that design decision? Also here is another problem I ran into when using
interfaces
<code>
interface Foo
{
Object clone();
}

class Bar : Foo
{
Bar clone()
{
return this;
}

}

void main()
{
Bar b = new Bar();
Bar c = b.clone(); //works fine

Foo f = b;
Foo g = f.clone(); //access violation
}
</code>
that one looks like a bug not able to explain whats wrong here, pardon me if im
missing something I'm still new to this language.

thanks for the replies so far.


June 13, 2006
In article <e6n4rl$kkm$1@digitaldaemon.com>, Frits van Bommel says...
>
>leoandru@gmail.com wrote:
>> I started coding in D a few days now but I ran into a few problems, I wasn't sure if these were bugs so I didnt make a bug report. the problem is with interface inheritance and method signatures It doesn't ssem to work as expected and I don't see any documentation saying otherwise.
>> 
>> interface A
>> {
>> void method();
>> }
>> 
>> 
>> interface B : A
>> {
>
>alias A.method method;
>
>> void method(int a);
>> }
>> 
>> 
>> class Foo : B
>> {
>
>void method()      { writefln("method()"); }
>void method(int a) { writefln("method(", a, ")"); }
>
>> }
>> 
>> 
>
>void main()
>{
>     B ref = new Foo();
>     ref.method();
>     ref.method(1);
>}
>/*
>> B ref = new Foo();
>> ref.method();   //doesnt compile, requires an argument.
>*/
>> 
>> This works if the method name in interface B is different from A, Im able to call method from interface. Am I doing something wrong? I expected this to work. I'm using dmd 0.160 compile on winxp. Thanks for any help/replies!
>
>The new method in B hides the one in A.
>With the above modifications it should compile and work.
>
>The use of 'alias' here and why it's necessary is explained in (among other places) http://www.digitalmars.com/d/function.html, under "Function Inheritance and Overriding":
>
><quote>
>However, when doing overload resolution, the functions in the base class
>are not considered:
>
>[...]
>
>To consider the base class's functions in the overload resolution process, use an /AliasDeclaration/:
>
>[...]
></quote>


Ok I see then that is just like writing the method signature of Interface A into
B. Is that really necessary? at least I expected interfaces to behave the way
they do in java or C#. hrm not what I expected, after all interface B is not an
override but rather and overloaded version. I wonder what was the reason behind
that design decision? Also here is another problem I ran into when using
interfaces
<code>
interface Foo
{
Object clone();
}

class Bar : Foo
{
Bar clone()
{
return this;
}

}

void main()
{
Bar b = new Bar();
Bar c = b.clone(); //works fine

Foo f = b;
Foo g = f.clone(); //access violation
}
</code>
that one looks like a bug not able to explain whats wrong here, pardon me if im
missing something I'm still new to this language.

thanks for the replies so far.


June 14, 2006
On Tue, 13 Jun 2006 21:56:40 +0000 (UTC), leoandru
<leoandru_member@pathlink.com> wrote:

><code>
>interface Foo
>{
>Object clone();
>}
>
>class Bar : Foo
>{
>Bar clone()
>{
>return this;
>}
>
>}
>
>void main()
>{
>Bar b = new Bar();
>Bar c = b.clone(); //works fine
>
>Foo f = b;
>Foo g = f.clone(); //access violation

Threre should be a cast to Foo: Foo g = cast(Foo)f.clone(). The code
works well for me (WinXP, D 0.160).

>}
></code>

Do you get access violation or AssertError? If it's AssertError, you might forget to put 'return' in a function that requirs a value to be returned (int main(...){return 0;}?). D doesn't warn about missing returns at compile time.

June 14, 2006
In article <3gav82l5bdkt0logigc3vokptkk35nrkvn@4ax.com>, Max Samuha says...
>
>On Tue, 13 Jun 2006 21:56:40 +0000 (UTC), leoandru
><leoandru_member@pathlink.com> wrote:
>
>><code>
>>interface Foo
>>{
>>Object clone();
>>}
>>
>>class Bar : Foo
>>{
>>Bar clone()
>>{
>>return this;
>>}
>>
>>}
>>
>>void main()
>>{
>>Bar b = new Bar();
>>Bar c = b.clone(); //works fine
>>
>>Foo f = b;
>>Foo g = f.clone(); //access violation
>
>Threre should be a cast to Foo: Foo g = cast(Foo)f.clone(). The code
>works well for me (WinXP, D 0.160).
>
>>}
>></code>
>
>Do you get access violation or AssertError? If it's AssertError, you might forget to put 'return' in a function that requirs a value to be returned (int main(...){return 0;}?). D doesn't warn about missing returns at compile time.
>


Yeah I had a return in the affected code in that example I returned a reference to the object itself. gessh! didn't know I had to cast ok thanks! I'll try that then.


June 14, 2006
On Wed, 14 Jun 2006 15:07:20 +0000 (UTC), leoandru
<leoandru_member@pathlink.com> wrote:

>In article <3gav82l5bdkt0logigc3vokptkk35nrkvn@4ax.com>, Max Samuha says...
>>
>>On Tue, 13 Jun 2006 21:56:40 +0000 (UTC), leoandru
>><leoandru_member@pathlink.com> wrote:
>>
>>><code>
>>>interface Foo
>>>{
>>>Object clone();
>>>}
>>>
>>>class Bar : Foo
>>>{
>>>Bar clone()
>>>{
>>>return this;
>>>}
>>>
>>>}
>>>
>>>void main()
>>>{
>>>Bar b = new Bar();
>>>Bar c = b.clone(); //works fine
>>>
>>>Foo f = b;
>>>Foo g = f.clone(); //access violation
>>
>>Threre should be a cast to Foo: Foo g = cast(Foo)f.clone(). The code
>>works well for me (WinXP, D 0.160).
>>
>>>}
>>></code>
>>
>>Do you get access violation or AssertError? If it's AssertError, you might forget to put 'return' in a function that requirs a value to be returned (int main(...){return 0;}?). D doesn't warn about missing returns at compile time.
>>
>
>
>Yeah I had a return in the affected code in that example I returned a reference to the object itself. gessh! didn't know I had to cast ok thanks! I'll try that then.
>

Sorry, I didn't notice that Bar implements Object clone() as Bar
clone(). The return types of the interface method and the method's
implementation differ. This seems to be illigal (At least, this is
illegal in C#). Anybody knows, why this compiles and works?