Re: Please explain this polymorphism twist to me.
Martin wrote:
Hi there,
I discovered a strange twist in polymorphism that leaves me in the
dark. If you can figure out what the following output will be, then
please explain to me why.
[...]
That means, the call "visitor.visit(this);" in the type Super is
handled by "Visitor.visit(Super)" instead of "Visitor.visit(Sub)".
This occurs as especially strange to me because a look in the debugger
confirms that the actual (dynamic) type of "this" is Sub! In my
opinion, the call should therefore be dynamically handled by
"Visitor.visit(Sub)".
Overloading != overriding.
Overloading is the practice of using one name to refer
to more than one thing. In this case, you use the name
`visit' to refer to two different methods, one taking a
Super as its argument and one taking a Sub (and having
different code inside them, too).
When a name is overloaded this way, the compiler needs
to figure out which of the possible methods is intended.
It does this by looking at the number and types of the
arguments you provide in the call, and (here's the crux)
the decision is made at compile time, based on the compile-
time types of the arguments. The compile-time type of the
`this' in the accept() method is Super, so the visit(Super)
version is the one that's called.
Here's a less convoluted demonstration of the same thing:
class Overload {
static void method(Object obj) {
System.out.println("obj = " + obj);
}
static void method(String str) {
System.out.println("str = " + str);
}
public static void main(String[] unused) {
String s = "Hello, world!";
method(s);
Object o = s; // run-time type is String
method(o); // compile-time type is Object
}
}
ISTR there's a discussion of this in Bloch's "Effective Java."
--
Eric.Sosman@sun.com