基础构造函数的Java调用基方法

时间:2011-08-28 19:44:33

标签: java inheritance

如何从Super :: Super()调用Super :: printThree?
在下面的例子中,我改为调用Test :: printThree。

class Super {
        Super() { 
        printThree(); // I want Super::printThree here!
        }
        void printThree() { System.out.println("three"); }
}
class Test extends Super {
        int three = 3
        public static void main(String[] args) {
                Test t = new Test();
                t.printThree();
        }
        void printThree() { System.out.println(three); }
}

output:
0    //Test::printThree from Super::Super()
3    //Test::printThree from t.printThree()

3 个答案:

答案 0 :(得分:11)

你不能 - 这是一个在子类中被覆盖的方法;你不能强制非虚方法调用。如果要非虚拟地调用方法,请将方法设为私有或最终。

一般来说,在构造函数中调用非final方法是一个坏主意,正是因为这个原因 - 子类构造函数体还没有被执行,所以你有效地在一个环境中调用一个方法已完全初始化。

答案 1 :(得分:1)

你违反了动态调度和继承背后的整个想法。只是不要这样做(而且无论如何都很难绕过java)。而是将函数设置为private和/或final,以便不能在继承的类

中覆盖它

答案 2 :(得分:1)

如果Super需要确保未覆盖printThree(),则需要将该方法声明为final。或者,Test中的重写方法可以决定在选择时调用overriden方法:

@Override
void printThree() { super.printThree(); }

如果基类没有将方法标记为final,它就放弃了不让派生类覆盖它并按照自己的意愿行事的权利。