【问题标题】: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 类,

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

        -考虑这种情况。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-02-26
          • 1970-01-01
          • 2013-03-13
          • 2018-05-06
          • 2016-06-07
          • 2013-02-18
          • 1970-01-01
          相关资源
          最近更新 更多