【发布时间】:2013-09-17 20:07:17
【问题描述】:
为什么超级方法应该将它的 this 引用作为超级类型而不是自己的类型分发?
我不明白这种行为的实用性。我学会了针对类型/接口而不是针对类进行编码,但是考虑到这种行为,我对我认为 OOP 所代表的一切感到困惑。这打破了干净代码的可能性,并迫使我用冗长的控制流来填充它,比如大量使用 instanceof 运算符。 为什么这种行为甚至有意义?
摘要:
考虑这段代码:
abstract class A {
public void visit(Target t) {
t.method(this);
}
}
如果 Target 重载 method() 并在其签名中使用 A 和 A 的不同子类,并且这些子类本身不覆盖 visit(Target t),则编译器将始终选择重载的 method(A a)。
工作示例: http://pastebin.com/EGNpY7pF
代码片段
public class Target {
public static abstract class A {
void visit(Target t) {
t.method(this);
}
}
public static class B extends A {}
public static class C extends A {
@Override
void visit(Target t) {
t.method(this);
}
}
void method(A a) { System.out.println("A");}
void method(B b) { System.out.println("B");}
void method(C c) { System.out.println("C");}
public static void main(String[] args) {
Target t = new Target();
A ab = new B();
B b = new B();
A ac = new C();
C c = new C();
ab.visit(t);
b.visit(t);
ac.visit(t);
c.visit(t);
}
}
输出
A A C C
这真的很糟糕,因为 ac 被引用为 A-Type 但仍然调用了 C 的覆盖 visit() 方法。
【问题讨论】:
-
您能否在您的问题中发布更完整的代码 sn-p,因为您的描述有点难以理解。
-
在
A中拥有该方法并不意味着实现被逐字复制到其每个子类中。任何地方都只有一份A.visit,而且那一份专门指重载t.method(A)。 -
这是您的代码,输出为ideone.com/1s14qi
-
我明白你在说什么,路易斯·瓦瑟曼。由于在
A的访问中,它在编译时决定如果没有子类覆盖visit()将调用method(),它是静态的而不是动态的。弱。
标签: java oop types overloading