覆盖派生类中的基类方法

时间:2013-05-15 07:01:58

标签: java inheritance

我有一个基类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(){};
}

重构1

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(){};
}

4 个答案:

答案 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