java – 在派生构造函数中调用super构造函数和设置字段值是否完全相同?

huangapple go评论81阅读模式
英文:

java - Is invoking super constructor in derived constructor same with set field value exactly?

问题

以下是你提供的内容的翻译:

在Java中,有两种定义派生类构造函数的方式。

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

我想知道的一件事是它们之间是否有任何区别?

我还知道DerivedClassWithSuper看起来代码更好,但我不确定如果我像在DerivedClassWithoutSuper中那样定义构造函数是否会有任何副作用。

class BaseClass {
    int id;
    BaseClass() {
        this.id = 0;
        System.out.printf("基类被创建,id:%d \n", this.id);
    }
}

class DerivedClassWithSuper extends BaseClass {
    String name;
    DerivedClassWithSuper() {
        super();
        // this.id = 0;
        this.name = "未知";
        System.out.printf("DerivedClassWithSuper被创建,this.id:%d,name:%s\n", this.id, this.name);
    }
}

class DerivedClassWithoutSuper extends BaseClass {
    String name;
    DerivedClassWithoutSuper() {
        this.id = 0;
        this.name = "未知";
        System.out.printf("DerivedClassWithoutSuper被创建,id:%d,name:%s\n", this.id, this.name);
    }
}

我始终感谢你的所有帮助。谢谢。


额外的问题:
如果没有super()函数,派生类会隐式调用super()

在下面稍作修改的代码中,在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("基类被创建,id:%d \n", this.id);
    }
}

class DerivedClassWithSuper extends BaseClass {
    String name;
    DerivedClassWithSuper() {
        super();
        this.name = "未知";
        System.out.printf("DerivedClassWithSuper被创建");
        System.out.printf("%d %d\n", this.id, super.id);
    }
}

class DerivedClassWithoutSuper extends BaseClass {
    String name;
    DerivedClassWithoutSuper() {
        // 如果隐式调用了super()?
        this.id = 10;
        this.name = "未知";
        System.out.printf("DerivedClassWithoutSuper被创建\n");
        // 然后this.id和super.id应该不同。
        // 但是,两者都是10,就像在此构造函数中设置的一样。
        System.out.printf("%d %d\n", this.id, super.id);
    }
}
英文:

There are two ways to define constructor of Derived class in java.

In DerivedClassWithSuper, I use super() function to define constructor.
But, in DerivedClassWithoutSuper I don't use super() function to define constructor.

One thing I want to know is that there are any difference between them?

I also know that DerivedClassWithSuper looks better code, but I'm not sure if there are any side effects when I define constructor like in 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);
    }
}

I always thanks for all your help. Thanks.


Additional Questions:
if there are not super() function, derived class call super() implicilty.

In the below code which is a little changed, In DerivedClassWithoutSuper constructor set this.id as 10, and it call super() function implicitly. if super() called, this.id or super.id should be set as 0.

But, super.id and this.id are 10.

I can't understand why this happen.

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

答案1

得分: 1

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

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

> 注意: 如果构造函数没有显式调用超类构造函数,Java编译器会自动插入对超类无参构造函数的调用。如果超类没有无参构造函数,你将会得到一个编译时错误。Object 这样的构造函数,因此如果Object是唯一的超类,就没有问题。

英文:

If a subclass constructor doesn't call super(...) (or this(...)) explicitly, the compiler will implicitly call the no-arg super() constructor for you. If no such constructor exists, compilation will fail, even though you never wrote the call.

See e.g. The Java™ Tutorials - Using the Keyword super:

> Note: If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error. Object does have such a constructor, so if Object is the only superclass, there is no problem.

huangapple
  • 本文由 发表于 2020年10月24日 16:00:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/64511235.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定