2011-08-28 118 views
0

如何从Super :: Super()调用Super :: printThree?
在下面的例子中,我改用Test :: printThree。基础构造函数的Java调用库方法

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() 

回答

11

你不能 - 它是一个在子类中被覆盖的方法;您不能强制进行非虚拟方法调用。如果你想非虚拟地调用一个方法,可以使该方法是私有的或最终的。

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

1

您违反了动态分配和继承背后的整个想法。不要这样做(并且很难在java中绕过)。取而代之的是使该功能是私有的和/或最终的,以使其不能被覆盖在继承的类中

1

如果Super需要确保printThree()未被覆盖,则该方法需要被声明为final。另外,在Test压倒一切的方法可以决定调用覆盖方法,如果选择:

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

如果基类没有标记方法final,它放弃权利,不具有派生类重写它并按他们的意愿去做。

+0

除了他不想在继承类中调用超级方法,而是相反。所以'super'的想法显然不会奏效,因为他的Super类的super是Object。 – Voo

+0

@Voo - 同意了,我只是指出了可能的情况。他想要的是不可能的。 –