web-dev-qa-db-ja.com

私は本当にJavaでデフォルトコンストラクタを定義する必要がありますか?

コンストラクターが定義されていない場合は正常に機能しますが、パラメーター化されたコンストラクターを定義し、デフォルトのコンストラクターではない場合はエラーが発生しますおよびオブジェクトの作成中に値を渡さない。コンストラクタはあらかじめ定義されていると思いました。

パラメータ化されたコンストラクタを定義しているのに、なぜデフォルトのコンストラクタを定義する必要があるのですか?デフォルトのコンストラクタは事前定義されていませんか?

32
Ayush Goyal

コンストラクタを自分で定義しない場合、デフォルト(引数なし)コンストラクタが自動的に作成されますonly

2つのコンストラクターが必要な場合、1つは引数あり、もう1つは引数なしで、両方を手動で定義する必要があります。

57
Justin Ardini

上記のすべての答えは正しいですが、初心者が頭にそれを包むのは少し難しいです。初心者の方は改めて質問に答えてみます。

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

言い換えると、パラメーター化されたコンストラクターを定義すると同時に、mustで引数のないコンストラクターも定義し、そのクラスのオブジェクトを引数なしのコンストラクタ。

また、継承の場合は、コンストラクターのないサブクラス。デフォルトのコンストラクタが1つ提供されます。上記のJavaによって提供されるデフォルトのコンストラクターは、スーパークラスの引数なしのコンストラクターを呼び出します。コンストラクターが見つからない場合は、エラーがスローされます。

したがって、引数なし/デフォルトのコンストラクタを定義することは常に良い選択です。

参照: Oracle Javaチュートリアル

13
Sahil J

引数を指定しない場合、引数なしのコンストラクタが自動的に挿入されます。つまり、いくつかのパラメーターを使用してコンストラクターを作成した場合、それが唯一のコンストラクターになるため、それらのパラメーターにいくつかの値を渡してインスタンスを作成する必要があります。

10
Noon Silk

これはまさに期待される動作です。

Javaは、コンストラクターを持たないクラスのデフォルト(引数コンストラクターなし)を自動的に生成します。

別のコンストラクターを(引数付きで)定義すると、デフォルトのコンストラクターは生成されません。それでも必要な場合は、自分で定義する必要があります。

2
daphshez

クラスがコンパイルされたとき、コンパイラーがクラス(default、parametrized)で有効なコンストラクターを見つけられない場合のみ、クラスの自動生成されたデフォルトコンストラクターを置き換えます

お気づきかもしれませんが、クラスで定義されたデフォルトコンストラクターなしでオブジェクトを作成できます。自動生成されたデフォルトコンストラクターの概念があります。オブジェクトが作成されるたびに、デフォルトコンストラクターが呼び出されます。

しかし、クラスでParametrizedコンストラクターを定義すると、オブジェクトがそのパラメーターを持つように制限されます

例:すべての従業員にはIDが必要です

したがって、その時点では、クラスに有効なコンストラクタがあるため、コンパイラはデフォルトのコンストラクタを挿入しません。デフォルトのコンストラクタも必要な場合は、自分で定義する必要があります。

1

非引数コンストラクターを定義しなければならない場合も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つの引数コンストラクターが既に存在する場合は、自動的に生成できません。

非常にまれなケースであることは知っていますが、知っておくと面白いと思いました。

0
EnGoPy