On Thu, 27 May 2010 17:00:08 -0400, bearophile <bearophileh...@lycos.com> wrote:

While answering to Larry Luther in a long thread in D.learn:
http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.learn&article_id=19913

I have found an interesting difference that I didn't know between Java and D. Here I have reduced the test cases:


// Java code
class A {
    void foo(A a) {}
}
class B extends A {
    void foo(B b) {}

    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        b.foo(a);
    }
}



// D2 code
class A {
    void foo(A a) {}
}
class B : A {
    void foo(B b) {}
}
void main() {
    A a = new A;
    B b = new B;
    b.foo(a);// comment this out and use warnings
}


If you comment out the last line in the D2 code, and you use warnings, DMD tells you at compile time:

test.d(5): Error: class test.B test.A.foo(A a) is hidden by B


If you uncomment that line DMD shows:

test.d(12): Error: function test.B.foo (B b) is not callable using argument types (A) test.d(12): Error: cannot implicitly convert expression (a) of type test.A to test.B


While the Java code compiles and runs with no errors.
It seems in D the B.foo() hides A.foo() even if there is no overriding at all here.

The presence of that warning tells me this is not an implementation bug, D is designed this way on purpose. But what is the rationale behind this difference (that at best will puzzle Java programmers trying to use D)?

This is actually the first question I posted on this newsgroup in 2007. It's called method "hijacking", look for it on the D website for a thorough explanation. Note that this is actually the default behavior in C++ (I didn't know until I asked the question and tried it, it's pretty obscure).

But the behavior is overridable, you can do this:

class B : A {
  alias A.foo foo;
  void foo(A a) {}
}

Which means "also look at A for resolving foo."

However, doing this may lead to further issues. I think if you had a class C that derived from B, calling B.foo(c) would result in an ambiguity without a cast.

-Steve

Reply via email to