我在最近的一次采访中被问到这个问题。想找人帮忙。
类具有从构造函数触发的foo()方法。
public class A {
public A() {
foo();
}
public void foo() {
System.out.println("In foo method in class A");
}
}
类b重写类a中的foo方法。
public class B extends A {
@Override
public void foo() {
System.out.println("In foo method in class B");
}
}
现在,如果我们创建类b的示例,将调用类b中的foo()方法。
A a = new B();
prints: "In foo method in class B"
问题:假设我们拥有类a,并且它是jar文件(.jar)的一部分,那么我们如何确保在示例化类b时调用a.foo()而不是重写b.foo()?
条件:
假设jar是共享给其他用户的,我们不能破坏我的客户机代码,将方法标记为private/final。
从类b调用super.foo()也不是一个选项,因为我们不拥有类b,也不能限制用户。
2条答案
按热度按时间de90aj5v1#
你做不到
A.foo()
,因为该方法被重写。只能使其调用A.foo()
调用,不能重写。这里更重要的一点是,您不应该从构造函数调用可重写的方法。
gab6jxml2#
标记a的
foo
方法asfinal
. 这是唯一的办法。为了仍然允许b在初始化时也获得ping,解决方案是两个阶段的构造:a的构造函数调用最终的foo()方法,但是作为foo()方法的一部分,也会调用foo2或subfo,或者您想调用它的任何东西,并且该方法在a中定义为noop(不执行任何操作)。
通常这种final init()风格的方法也应该是私有的。基于通用逻辑:“init”操作也是一个概念,外部代码可能会在以后的任意时间点再次调用这个概念,这种可能性有多大?不太可能,这就是为什么它应该是私人的。一旦你这么做了,私有方法实际上是最终的,所以这就解决了: