【发布时间】:2014-02-26 17:22:57
【问题描述】:
假设我们有以下代码:
class A {
public void doLogic() {
System.out.println("doLogic from A");
}
}
class B extends A {
@Override
public void doLogic() {
System.out.println("doLogic from B");
}
public void doDifferentLogic() {
System.out.println("doDifferentLogic from B");
super.doLogic();
}
}
class C extends B {
@Override
public void doLogic() {
System.out.println("doLogic from C");
}
}
public class Test {
public static void main(String[] args) {
C c = new C();
c.doDifferentLogic();
}
}
当我们执行这段代码时,预期的行为如下:
由于 c 持有对 C 类对象的引用,因此当您调用 c.doDifferentLogic() 方法时,JVM 会在 C 类中搜索该方法,并且由于找不到它,它开始查看继承树。正如预期的那样,doDifferentLogic() 方法在超类中找到并执行。但是构造 super.doLogic() 应该从 C 类型的当前引用“Point of View”中查找。因此 C 的超类应该是 B,而是调用顶级类 A 中的方法。
如果您删除 super 关键字,或将其替换为 this 关键字(与“this”是隐式的相同),您将获得预期的多态行为,并调用 C 类中的 doLogic() .
所以我的问题是:
应该调用super.doLogic() 是this.super.doLogic()(2),而不是static.super.doLogic()(1)?
两者都是无效的结构,他们在这里只是为了更好地解释自己。
(1) 或者换句话说 - 从对当前对象 c 的引用中,获取当前对象的超类并调用 doLogic() 方法而不是
(2)从这个类中获取超类并调用它的doLogic()方法?
【问题讨论】:
-
是否有这样的情况会如所描述的那样发生,或者您为什么希望它以这种方式发生?它不会冒着意外/隐式修改 B.doDifferentLogic() 的实现的风险吗?
-
如果我理解你的问题,你问的是从你的类的其他公共方法中调用公共方法是否是糟糕的设计 - 是的。如果你想保证 doDifferentLogic() 在子类中的行为总是相同的,你应该将 doLogic() 设为私有,如果你想让这两个方法都公开,你应该从公共方法中调用私有方法,如下所示:@Override public void doLogic() { doPrivateLogic() } private void doPrivateLogic() { System.out.println("doLogic from B"); }
标签: java inheritance super