java 为什么子类构造函数必须显式调用超类构造函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14250486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 15:36:58  来源:igfitidea点击:

Why exactly do subclass constructors have to explicitly call super class constructors?

java

提问by John W

Possible Duplicate:
Why does this() and super() have to be the first statement in a constructor?

可能的重复:
为什么 this() 和 super() 必须是构造函数中的第一条语句?

Why exactly do subclass constructors have to explicitly call super class constructors? What is the reason for this?

为什么子类构造函数必须显式调用超类构造函数?这是什么原因?

回答by Jon Skeet

They don't.

他们没有。

If you don't explicitly call a superconstructor, it's equivalent to calling the parameterless superconstructor.

如果不显式调用超构造函数,就相当于调用了无参数的超构造函数。

public class Sub
{
    public Sub()
    {
        // Do some stuff
    }
}

is equivalent to:

相当于:

public class Sub
{
    public Sub()
    {
        super();
        // Do some stuff
    }
}

You doexplicitly have to call a superconstructor if you want to specify arguments. That's pretty reasonable, IMO - would you really want the compiler guessingwhich arguments you wanted to supply?

明确要调用一个超类,如果你想指定的参数。这是非常合理的,IMO - 您真的希望编译器猜测您想要提供哪些参数吗?

回答by Abhishekkumar

subclass implicitly call even default constructor present in super class which is non parameterised. We have to call explicitly when we pass parameters to the constructor.

子类甚至隐式调用超类中存在的默认构造函数,它是非参数化的。当我们将参数传递给构造函数时,我们必须显式调用。

回答by Yona Appletree

As mentioned above, you only have to invoke a super constructor if there isn't a default constructor in the parent class.

如上所述,如果父类中没有默认构造函数,则只需调用超级构造函数。

This is required because the parent class must be initialized by one of its constructors, and if there isn't a default constructor, the java compiler has no way of knowing which constructor to call, or what parameters need to be passed.

这是必需的,因为父类必须由其构造函数之一初始化,如果没有默认构造函数,java 编译器无法知道调用哪个构造函数,或者需要传递哪些参数。

To better understand why at least one constructor in the parent must be called, consider the following:

为了更好地理解为什么必须至少调用父级中的一个构造函数,请考虑以下内容:

class Person {
    private Person mother;
    private Person father;

    public Person(Person mother, Person father) {
        assert mother != null && father != null: "Parents can't be null!";

        this.mother = mother;
        this.father = father;
    }

    public boolean hasAnyLivingParents() {
        return mother.isAlive() || father.isAlive();
    }

    public boolean isAlive() { return true; }
}

If you create a Persondirectly, you must specify the motherand fatherof the person, and the hasAnyLivingParents()method expects these to be specified.

如果Person直接创建 a ,则必须指定人员的motherfather,并且该hasAnyLivingParents()方法需要指定这些。

Now, consider you have a subclass, Employee, and you don't care about the parents of an Employee, so you want to write something like this:

现在,假设您有一个子类 Employee,并且您不关心 Employee 的父类,因此您想编写如下内容:

class Employee extends Person {
    double salary;

    public Employee(double salary) { 
        this.salary = salary;
    }
}

This won't compile because we don't call a constructor of Person, and there isn't a default constructor. If this didcompile, calling (new Employee(50000d)).hasAnyLivingParents()would alwaysthrow a NullPointerException, since nothing even initialized the motherand fatherfields.

这不会编译,因为我们没有调用 的构造函数Person,并且没有默认构造函数。如果这确实编译,调用(new Employee(50000d)).hasAnyLivingParents()始终抛出 a NullPointerException,因为甚至没有初始化motherfather字段。

In short, java requiresthat every class be initialized by some constructor. If there isn't a default constructor on a class, one of its other constructors mustbe called for the object to be initialized.

简而言之,java要求每个类都由某个构造函数初始化。如果类上没有默认构造函数,则必须调用其其他构造函数之一来初始化对象。

回答by Juvanis

class Parent
{ 
   Parent(int x) {}
}

class Child extends Parent
{
   Child(){} // will not compile.
}

Compiler tries to invoke super()as the first line of Child()constructor but the parent doesn't have no-arg constructor. So in this case you have to do it explicitly by calling super(5), for example.

编译器尝试super()作为Child()构造函数的第一行调用,但父级没有无参数构造函数。因此,在这种情况下,您必须通过调用显式地执行此操作super(5),例如。