コンストラクターが定義されていない場合は正常に機能しますが、デフォルトではなくパラメーター化されたコンストラクターを定義し、オブジェクトの作成中に値を渡さない場合はエラーが発生します。コンストラクターは事前定義されていると思いました。
パラメーター化されたコンストラクターを定義したのに、なぜデフォルトのコンストラクターを定義する必要があるのですか?デフォルトのコンストラクターは事前定義されていませんか?
コンストラクターが定義されていない場合は正常に機能しますが、デフォルトではなくパラメーター化されたコンストラクターを定義し、オブジェクトの作成中に値を渡さない場合はエラーが発生します。コンストラクターは事前定義されていると思いました。
パラメーター化されたコンストラクターを定義したのに、なぜデフォルトのコンストラクターを定義する必要があるのですか?デフォルトのコンストラクターは事前定義されていませんか?
デフォルト(引数なし)のコンストラクターは、コンストラクターを自分で定義しない場合にのみ自動的に作成されます。
1つは引数あり、もう1つは引数なしの、2つのコンストラクターが必要な場合は、両方を手動で定義する必要があります。
上記のすべての答えは正しいですが、新参者がそれを頭に包むのは少し難しいです。新規参入者の方は、改めてご質問にお答えします。
Ayushが直面していた問題は、Object
引数なしのコンストラクターを介してクラスのをインスタンス化しようとしたことでした。ただし、このクラスには1つ以上のパラメーター化されたコンストラクターがあり、コンパイル時エラーが発生します。
たとえばStudent
、単一のパラメーター化されたコンストラクターを使用してクラスを作成し、引数なしのコンストラクターを介してインスタンス化してみましょう。
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"
}
}
うわ!しかし、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();
}
}
つまり、パラメーター化されたコンストラクターを定義する瞬間に、引数なしのコンストラクターを介してそのクラスのオブジェクトをインスタンス化する場合は、引数なしのコンストラクターも定義する必要があります。
また、継承の場合、コンストラクターのないサブクラス。1つのデフォルトコンストラクタが提供されます。上記のようにJavaによって提供されるこのデフォルトのコンストラクターは、スーパークラスの引数なしコンストラクターを呼び出します。見つからない場合は、エラーがスローされます。
したがって、引数なし/デフォルトのコンストラクターを定義することは常に良い選択です。
引数を作成しない場合は、引数なしのコンストラクターが自動的に挿入されます。つまり、いくつかのパラメーターを使用してコンストラクターを作成する場合、それが唯一のコンストラクターになるため、インスタンスを作成するには、それらのパラメーターにいくつかの値を渡す必要があります。
これはまさに予想される動作です。
Javaは、コンストラクターを持たないクラスのデフォルト(引数コンストラクターなし)を自動的に生成します。
(引数を使用して)別のコンストラクターを定義すると、デフォルトのコンストラクターは生成されません。それでも必要な場合は、自分で定義する必要があります。
クラスがコンパイルされるときはいつでも、コンパイラーがクラス内に有効なコンストラクター(default、parametrized)を見つけられない場合にのみ、自動生成されたデフォルトのコンストラクターをクラスに置き換えます。
お気づきのことと思いますが、クラスでデフォルトコンストラクターを定義しなくてもオブジェクトを作成できます。自動生成されたデフォルトコンストラクターの概念があります。オブジェクトが作成されるたびに、デフォルトコンストラクターが呼び出されます。
ただし、クラスでパラメーター化されたコンストラクターを定義する場合は、オブジェクトがそのパラメーターを持つように制限することを意味します
例:すべての従業員はIDを持っている必要があります。
そのため、その時点では、クラスに有効なコンストラクターがあるため、Compilerはデフォルトのコンストラクターを挿入しません。デフォルトのコンストラクターも必要な場合は、自分で定義する必要があります。
引数以外のコンストラクターを定義する必要があるという奇妙なケースも1つあります。他の人が書いたように、デフォルトのコンストラクターを指定しない場合、Javaが自動的に行います。「Javaによって生成されたデフォルト」コンストラクターがどのように見えるかを理解するのは良いことです。実際、スーパークラスのコンストラクターを呼び出しますが、これは問題ありません。ここで、1つのケースを想像してみましょう。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つの引数のコンストラクターが1つだけ定義されています。次に、Vehicleクラスから継承するCarクラスを作成しましょう。
public class Car extends Vehicle {
@Override
public String makeNoise() {
return "Wrrrrrrr....";
} }
奇妙に見えるかもしれませんが、コンパイルされない理由の1つは、JavaがスーパーVehicleクラスを呼び出すCarクラスのデフォルトコンストラクターを作成できないことです。Vehicleクラスには引数コンストラクターがなく、2つの引数コンストラクターが既に存在する場合は自動的に生成できません。
非常にまれなケースであることは知っていますが、知っておくと面白いと思いました。