Java编译器super()构造函数总览

6
可能重复:访问未覆盖超类方法时使用'super'关键字 我是Java的新手,最近一直在阅读有关该语言的知识和经验。我对继承方法和扩展类以及编译器自动插入代码有一个问题。
我已经阅读了这样一个观点:如果我创建一个带有一些方法的A类,包括称为checkDuePeriod()的方法,然后创建一个扩展A类及其方法的B类。
如果我在B类中调用checkDuePeriod()方法而不使用super.checkDuePeriod()语法,则在编译期间编译器是否会在checkDuePeriod()之前加上super.,或者编译器自动在编译类时包含super()构造函数是否意味着B类从A类调用的方法需要super.调用?
我对此有点困惑。先谢谢您。

这个线程可能会有所帮助:https://dev59.com/HWnWa4cB1Zd3GeqPz2Lc - jcern
构造函数与你的问题有什么关系? - user207421
4个回答

5

超类的常规方法实现不会自动在子类中调用,但是子类的构造函数必须调用超类的某种形式的构造函数。

在某些情况下,对 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);
    }
}

1

在 IT 相关领域中,使用 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;
    }
}

1
如果在B中调用checkDuePeriod()而没有使用super.,这意味着您想调用属于B的此实例(由B内的this表示)的方法。因此,它相当于说this.checkDuePeriod(),所以编译器在前面添加super.是没有意义的。 super.是必须显式添加的内容,以告诉编译器您要调用A版本的方法(特别是在B覆盖了A提供的方法实现的情况下需要)。

0

首先讲一下构造函数:

- 每当创建一个类的对象时,它的构造函数被初始化,并且立即调用其超类构造函数,直到Object类。

- 在此过程中,所有实例变量都被声明和初始化。

- 考虑以下情况。

DogCanine子类,而Canine是Animal子类

现在当Dog对象被初始化时,在对象实际形成之前,必须形成Canine类对象,而在Canine对象形成之前,必须形成Animal类对象,而在此之前必须形成Object类对象,

因此,对象形成的顺序为:

Object ---> Animal ---> Canine ---> Dog

所以超类的构造函数在子类之前被调用

现在有了Method

该类调用的最具体版本的方法。

例如:

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
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接