【问题标题】:Is super() called when this() is called inside a constructor在构造函数中调用 this() 时是否调用 super()
【发布时间】:2015-08-02 19:05:04
【问题描述】:

我知道构造函数中的第一条语句必须是 super()(或 this()),如果没有明确指定,编译器会为我们插入它。考虑到这一点,请参阅以下代码:

    class Building {
            Building() {  System.out.print("b ");  }
            Building(String name) {

       }
     }
     public class House extends Building {
      House() {  System.out.print("h ");  }
      House(String name) {
        this();   System.out.print("hn " + name);
      }
      public static void main(String[] args) { new House("x "); }
     }

在 main 方法中,我调用了 House 类的重载构造函数,该构造函数接受一个 String 参数。由于 this() 已经被调用,这意味着 super() 被隐式调用。但是 Building(String name) 构造函数会发生什么?不是也得叫吗?我知道这段代码可以工作并产生b h hn x,但不需要调用超类的匹配构造函数吗?

【问题讨论】:

  • 但不匹配构造函数:您假设基类中的构造函数通过参数与子类构造函数匹配,House(String) 会自动调用Building(String)? (提示:事实并非如此)。

标签: java constructor


【解决方案1】:

您需要调用基类的一个构造函数,并且恰好是一个构造函数。在您的示例中,正如您正确地说的那样,将调用 Building 类的无参数构造函数。不会调用单参数构造函数。

基类构造函数和派生类构造函数之间不需要匹配参数名称或类型。

【讨论】:

  • 好的,如果在 House(String name) 构造函数中没有调用 this() 会隐式调用哪个 Building 构造函数?
  • 无参数的。如果需要调用带参数的基类的构造函数,则始终需要显式调用super()。
  • @MikeJM 它将调用父类的默认无参数构造函数
  • 嗯,我明白了。所以隐式调用只对无参数构造函数进行,基类和子类的签名之间绝对没有关系。我说的对吗?
【解决方案2】:

让我们在代码的每一行加上数字,以便更容易解释指针将在哪里执行代码:

    1 class Building {
    2     Building() { System.out.print("b ");  }
    3     Building(String name) { } 
    4 }
    5
    6 public class House extends Building {
    7
    8     House() {  System.out.print("h ");  }
    9     House(String name) { this(); System.out.print("hn " + name); }
   10 
   11     public static void main(String[] args) { new House("x "); }
   12 }

当您致电new House("x "); 时,会发生以下情况:

/*11*/ new House("x ") --              --> "b h hn x"
                        |             |
                /*9*/ this(); System.out.print("hn " + name); /* House(name) */ 
                        |             ^
                        v             |
                /*8*/ super(); System.out.print("h ");        /* House() */
                        |             ^
                        v             |
                /*2*/ super(); System.out.print("b ");        /* Building() */
                        |             ^
                        v             |
                      super() -------->                       /* Object() */  
            /* The super of Object() does nothing. let's go down. */

and all these calls will print : "b h hn x" as expected :)

每次创建构造函数时,如果不显式调用另一个构造函数,则隐式调用 super();

(在你的情况下,Building 的构造函数)。

【讨论】:

  • 感谢漂亮的草图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-17
  • 2011-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-17
  • 2011-02-12
相关资源
最近更新 更多