Method hiding
Steven Schveighoffer
schveiguy at yahoo.com
Thu May 27 14:11:55 PDT 2010
On Thu, 27 May 2010 17:00:08 -0400, bearophile <bearophileHUGS at 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
More information about the Digitalmars-d
mailing list