我有一个基类A,有一个方法“说”从A的构造函数调用。所有可遗漏的类都使用方法“说”就像它一样。但其中一个类需要重新定义这种方法。这怎么可能?
当然,我可以将基本方法“说”视为抽象,但是这样,我必须在所有可遗漏的类中复制相同的方法“说”。
如果我只重新定义方法而不将基类表示为抽象,那么它就不会被调用。
public abstract class A(){
public A(){
say(); // <- wanna call this method from heritable class, if its redefined.
}
protected void say(){};
}
public class B extends A(){
public B(){
super();
}
private void say(){};
}
public abstract class A(){
public A(){
// constructor methods
}
protected void say(){};
protected void executeSay(){
say();
}
}
public class B extends A(){
public B(){
super();
executeSay();
}
@Override
protected void say(){};
}
答案 0 :(得分:11)
首先必须弄清楚:从构造函数调用可覆盖的方法是一个众所周知的反模式。它几乎肯定会破坏你的代码,因为子类方法将在子类构造函数完成之前调用 ,因此会观察一个未初始化的对象。因此,我最好不要向您提供有关实现此反模式的Java技术的详细建议。
实现您的要求的唯一安全方法是让构造完成,然后才调用initialize
种方法。如果要确保始终调用initialize
,请使构造函数非公共,并提供工厂方法。
不幸的是,Java需要您做很多工作才能使其正常工作。
答案 1 :(得分:4)
您无法实例化抽象类。这就是说你必须将抽象类引用链接到具体的继承类。 例如。 A =新B(); 如果是这种情况,并且B重新定义了say()方法,那么将调用B中的say方法。
public class TestPad {
public static void main(String[] args) {
A a = new B();
}
}
abstract class A {
public A() {
say();
}
public void say(){
System.out.println("A");
};
}
class B extends A {
public B() {
super();
}
public void say() {
System.out.println("B");
}
}
输出为B
答案 2 :(得分:3)
public class B extends A {
public B() {
super();
}
@Override
protected void say() {
// your diffent say code
};
}
我不确定你是否被允许降低私密性。
答案 3 :(得分:0)
由于多态方法调用,在你的情况下,如果你覆盖它,将调用B.say()。
但正如@sanbhat所评论的那样,您需要将say()
的可见性更改为protected
。