【问题标题】:Java compiler super() constructor generals [duplicate]Java编译器super()构造函数将军[重复]
【发布时间】:2012-10-07 06:29:18
【问题描述】:
可能重复:
Use of ‘super’ keyword when accessing non-overridden superclass methods
我是 Java 新手,最近阅读了很多关于它的内容,以获取有关该语言的更多知识和经验。当编译器插入自动代码时,我有一个关于继承方法和扩展类的问题。
我一直在阅读,如果我使用一些方法创建类 A,包括让我们说一个名为 checkDuePeriod() 的方法,然后创建一个扩展类 A 及其方法的类 B。
如果我随后在 B 类中调用方法 checkDuePeriod() 而不使用 super.checkDuePeriod() 语法,则在编译期间编译器将在 checkDuePeriod() 之前包含 super. 或者编译器包含 super() 构造函数的事实编译类时自动暗示B类从A类调用的方法的super.调用?
我对此有点困惑。提前致谢。
【问题讨论】:
标签:
java
class
inheritance
compiler-construction
constructor
【解决方案1】:
超类的常规方法实现不会在子类中自动调用,但必须在子类的构造函数中调用超类构造函数的一种形式。
在某些情况下,对super() 的调用是隐含的,例如当超类具有默认(无参数)构造函数时。但是,如果超类中不存在默认构造函数,则子类的构造函数必须直接或间接调用超类的构造函数。
默认构造函数示例:
public class A {
public A() {
// default constructor for A
}
}
public class B extends A {
public B() {
super(); // this call is unnecessary; the compiler will add it implicitly
}
}
没有默认构造函数的超类:
public class A {
public A(int i) {
// only constructor present has a single int parameter
}
}
public class B extends A {
public B() {
// will not compile without direct call to super(int)!
super(100);
}
}
【解决方案2】:
如果你在B中调用checkDuePeriod()而没有super.,则表示你要调用属于B的this实例(在B中用this表示)的方法。所以,相当于说this.checkDuePeriod() ,所以编译器在前面添加super. 是没有意义的。
super. 是您必须显式添加的内容,以告诉编译器您要调用 A 的方法版本(特别需要它,以防 B 覆盖了 A 为该方法提供的实现)。
【解决方案3】:
作为默认构造函数(没有参数的构造函数)调用 super() 可以是直接的或非直接的,但它保证可扩展类的字段已正确初始化。
例如:
public class A {
StringBuilder sb;
public A() {
sb = new StringBuilder();
}
}
public class B extends A {
public B() {
//the default constructor is called automatically
}
public void someMethod(){
//sb was not initialized in B class,
//but we can use it, because java garants that it was initialized
//and has non null value
sb.toString();
}
}
但在方法的情况下:
方法实现了一些逻辑。如果我们需要重写我们使用的超类的逻辑
public class B extends A {
public B() {
}
public boolean checkDuePeriod(){
//new check goes here
}
}
如果我们只想实现一些额外的检查,使用从超类的 checkDuePeriod() 返回的值,我们应该这样做
public class B extends A {
public B() {
}
public boolean checkDuePeriod(){
if(super.checkDuePeriod()){
//extra check goes here
}else{
//do something else if need
}
return checkResult;
}
}
【解决方案4】:
首先关于Constructors:
-当一个类的object被创建时,它的constructor被初始化并且在那个时候立即它的s@987654325的constructor @ 被调用直到 Object 类,
-在这个过程中,所有的实例变量都被声明和初始化。
-考虑这种情况。
Dog 是 Canine 的 sub-class,而 Canine 是 Animal
的
sub-class
现在初始化Dog对象时,在对象真正形成之前,必须先形成Canine类对象,在Canine对象形成之前,先形成Animal类对象,再形成Object类对象,
所以形成的对象顺序为:
Object ---> Animal ---> Canine ---> Dog
所以Constructor of the Super-Class is Called before the Sub-Class。
现在使用Method:
The most specific version of the method that class is called.
例如:
public class A{
public void go(){
}
}
class B extends A{
public static void main(String[] args){
new B().go(); // As B has not overridden the go() method of its super class,
// so the super-class implementation of the go() will be working here
}
}