【问题标题】:java - Is invoking super constructor in derived constructor same with set field value exactly?java - 在派生构造函数中调用超级构造函数是否与设置字段值完全相同?
【发布时间】:2023-03-10 05:48:01
【问题描述】:

在java中定义Derived类的构造函数有两种方式。

DerivedClassWithSuper 中,我使用super() 函数来定义构造函数。 但是,在DerivedClassWithoutSuper 中,我不使用super() 函数来定义构造函数。

我想知道的一点是它们之间有什么区别?

我也知道DerivedClassWithSuper 看起来更好的代码,但我不确定当我像DerivedClassWithoutSuper 那样定义构造函数时是否有任何副作用

class BaseClass {
    int id;
    BaseClass () {
        this.id = 0;
        System.out.printf("Base class is created, id: %d \n", this.id);
    }
}

class DerivedClassWithSuper extends BaseClass {
    String name;
    DerivedClassWithSuper () {
        super(); 
        // this.id = 0;
        this.name = "Unknown";
        System.out.printf("DerivedClassWithSuper is created, this.id: %d, name: %s\n", this.id, this.name);
    }
}

class DerivedClassWithoutSuper extends BaseClass {
    String name;
    DerivedClassWithoutSuper () {
        this.id = 0;
        this.name = "Unknown";
        System.out.printf("DerivedClassWithoutSuper is created, id: %d, name: %s\n", this.id, this.name);
    }
}

我一直感谢您的帮助。谢谢。


其他问题: 如果没有super()函数,派生类调用super() implicilty。

在下面稍作改动的代码中,DerivedClassWithoutSuper 构造函数中将this.id 设置为10,并隐式调用super() 函数。如果调用super(),则this.idsuper.id应设置为0。

但是,super.idthis.id 是 10。

我不明白为什么会这样。

class BaseClass {
    int id;
    BaseClass () {
        this.id = 0;
        System.out.printf("Base class is created, id: %d \n", this.id);
    }
}

class DerivedClassWithSuper extends BaseClass {
    String name;
    DerivedClassWithSuper () {
        super();
        this.name = "Unknown";
        System.out.printf("DerivedClassWithSuper is created");
        System.out.printf("%d %d\n", this.id, super.id);
    }
}

class DerivedClassWithoutSuper extends BaseClass {
    String name;
    DerivedClassWithoutSuper () {
        // if super() implicitly called?
        this.id = 10;
        this.name = "Unknown";
        System.out.printf("DerivedClassWithoutSuper is created\n");
        // then this.id and super.id should be different. 
        // but, both are 10 as set in this constructor. 
        System.out.printf("%d %d\n", this.id, super.id);
    }
}

【问题讨论】:

  • super() 没有“定义构造函数”。它调用 parent 构造函数。不清楚你在问什么。
  • 1) this.id = 0; 是多余的,因为数字字段默认为 0。 --- 2) 是的,super() 在构造函数开始时被隐式调用,如果没有显式调用。 --- 3) idthis.idsuper.id all 指的是 BaseClass 的唯一 id 字段。 --- 4) 为什么id 在你赋予它那个值之后不会是10

标签: java inheritance constructor


【解决方案1】:

如果子类构造函数没有显式调用super(...)(或this(...)),编译器将为您隐式调用无参数super() 构造函数。如果不存在这样的构造函数,即使您从未编写过调用,编译也会失败。

参见例如The Java™ Tutorials - Using the Keyword super:

注意:如果构造函数没有显式调用超类构造函数,Java 编译器会自动插入对超类的无参数构造函数的调用。如果超类没有无参数构造函数,则会出现编译时错误。 Object确实有这样的构造函数,所以如果Object是唯一的超类,没有问题。

【讨论】:

  • super(...) (or this(...)) ? this(...)super(...) 不一样!即使你有this(...),你也会得到错误!
  • @tashkhisi 我从来没有说过this(...)super(...)一样,但是所有的构造函数(除了Object()构造函数) 必须 显式或隐式调用另一个构造函数。你可以调用this(...)或者你可以调用super(...)或者你可以让编译器隐式调用super()
  • 我明白你的意思。
  • 感谢您的帮助。我添加了其他问题。非常感谢您的帮助
  • @frhyme 不要在问题中添加更多问题。每个问题只有一个问题,因此请创建一个新问题。
猜你喜欢
  • 1970-01-01
  • 2018-07-21
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
  • 1970-01-01
  • 2016-07-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多