当未定义构造函数时,它工作正常,但如果我定义参数化构造函数而不是默认值并且在创建对象时不传递任何值,则会出错。我认为构造函数是预定义的。
如果我定义了参数化构造函数,为什么还需要定义默认构造函数?是不是预定义了默认构造函数?
答案 0 :(得分:55)
如果您自己没有定义任何构造函数,则会自动创建默认(无参数)构造函数 。
如果你需要两个构造函数,一个带参数,一个没有,你需要手动定义它们。
答案 1 :(得分:13)
虽然上面的所有答案都是正确的,但对于新来者来说,把它包裹起来有点困难。我将尝试为新来者重新回答这个问题。
Ayush面临的问题是尝试通过no-arg构造函数为类实例化Object
。但是,这个类有一个或多个参数化构造函数,这会导致编译时错误。
例如,让我们创建一个带有单个参数化构造函数的类Student
,并尝试通过no-arg构造函数对其进行实例化。
public class Student {
private String name;
private int rollNo;
public Student(String name, int rollNo) {
this.name = name;
this.rollNo = rollNo;
}
public static void main(String[] args) {
// The line below will cause a compile error.
Student s = new Student();
// Error will be "The constuctor Student() is undefined"
}
}
WOHA!但是当我们删除public Student(String name, int rollNo)
时
构造函数在一起,错误消失,代码编译。
这种看似异常的原因在于只有Java这一事实 当我们没有定义任何构造函数时,它为我们提供了默认(无参数)构造函数 我们自己的那个类的构造函数。
例如,以下类提供了默认的构造函数:
public class Student {
private String name;
private int rollNo;
}
变为:
public class Student {
private String name;
private int rollNo;
//Default constructor added by Java.
public Student() {
super();
}
}
换句话说,我们定义任何参数化构造函数的那一刻, 如果我们想要实例化,我们必须也定义一个无参数构造函数 通过no-arg构造函数实现该类的对象。
同样在继承的情况下,没有构造函数的子类;提供一个 默认构造函数。 Java提供的这个默认构造函数调用了超类的无参数构造函数。如果找不到,那么就会抛出错误。
所以是的,定义一个no-arg / default构造函数总是一个不错的选择。
答案 2 :(得分:10)
如果你不写一个no-arg构造函数会自动为你插入。这意味着,如果您使用某些参数编写构造函数,它将是您拥有的唯一构造函数,因此您必须为这些参数传递一些值以创建它的实例。
答案 3 :(得分:2)
这正是预期的行为。
Java为没有任何构造函数的类自动生成默认(无参数构造函数)。
如果定义另一个构造函数(带参数),则不会生成默认构造函数。如果你还想要一个,你需要自己定义它。
答案 4 :(得分:1)
每当你的类被编译时,如果编译器在类中没有找到任何有效的构造函数(默认,参数化),那么它将替换你的类的自动生成的默认构造函数。
你一定注意到,你可以创建没有在你的类中定义任何默认构造函数的对象,有自动生成的默认构造函数的概念。每当创建对象时,都会调用默认构造函数。
但是,如果在类中定义Parametrized构造函数,则意味着您将对象限制为具有该参数
示例:每位员工都必须拥有ID。
那么,那时,编译器不会在那里插入任何默认构造函数,因为类中有有效的构造函数。如果你也需要默认构造函数,你必须自己定义。
答案 5 :(得分:0)
当您必须定义非参数构造函数时,还有一种奇怪的情况。 正如其他人所写,如果您不指定默认构造函数-Java会为您完成。很高兴了解“ Java默认生成的”构造函数的外观。 实际上,它调用了超类的构造函数,这很好。 现在让我们想象一个案例。 您正在创建Vehicle类:
public class Vehicle {
private String name;
private String engine;
public Vehicle(String name, String engine) {
this.name = name;
this.engine = engine;
}
public String makeNoise(){
return "Noiseee";
}
}
我们可以看到Vehicle类只有一个已定义的2参数构造函数。 现在让我们创建从Vehicle类继承的Car类:
public class Car extends Vehicle {
@Override
public String makeNoise() {
return "Wrrrrrrr....";
} }
也许看起来很奇怪,但是为什么不能编译的唯一原因是Java无法为调用超级Vehicle类的Car类创建默认构造函数。 Vehicle类没有参数构造函数,并且在已经存在2个arg构造函数的情况下无法自动生成。
我知道这是非常罕见的情况,但是我发现这很有趣。