重複の可能性:
this() と super() をコンストラクターの最初のステートメントにする必要があるのはなぜですか?
サブクラスのコンストラクターがスーパークラスのコンストラクターを明示的に呼び出さなければならないのはなぜですか? これの理由は何ですか?
重複の可能性:
this() と super() をコンストラクターの最初のステートメントにする必要があるのはなぜですか?
サブクラスのコンストラクターがスーパークラスのコンストラクターを明示的に呼び出さなければならないのはなぜですか? これの理由は何ですか?
彼らはしません。
スーパーコンストラクターを明示的に呼び出さない場合は、パラメーターなしのスーパーコンストラクターを呼び出すのと同じです。
public class Sub
{
public Sub()
{
// Do some stuff
}
}
次と同等です。
public class Sub
{
public Sub()
{
super();
// Do some stuff
}
}
引数を指定する場合は、スーパーコンストラクターを明示的に呼び出す必要があります。それはかなり合理的です、IMO-あなたが提供したい引数をコンパイラーに推測させたいですか?
サブクラスは、パラメーター化されていないスーパークラスに存在するデフォルトのコンストラクターも暗黙的に呼び出します。コンストラクターにパラメーターを渡すときは、明示的に呼び出す必要があります。
前述のように、親クラスにデフォルト コンストラクターがない場合にのみ、スーパー コンストラクターを呼び出す必要があります。
これが必要なのは、親クラスがそのコンストラクターの 1 つによって初期化される必要があるためです。また、デフォルトのコンストラクターがない場合、Java コンパイラーは呼び出すコンストラクターや、渡す必要のあるパラメーターを知る方法がありません。
親の少なくとも 1 つのコンストラクターを呼び出す必要がある理由をよりよく理解するには、次の点を考慮してください。
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; }
}
Person
を直接作成する場合は、人物のmother
andを指定する必要があり、メソッドはこれらが指定されることを想定しています。father
hasAnyLivingParents()
ここで、サブクラス Employee があり、Employee の親を気にしないとします。したがって、次のように記述します。
class Employee extends Person {
double salary;
public Employee(double salary) {
this.salary = salary;
}
}
のコンストラクターを呼び出さPerson
ず、デフォルトのコンストラクターがないため、これはコンパイルされません。これがコンパイルされた場合、とフィールドを初期化するものさえ何もないため、呼び出し(new Employee(50000d)).hasAnyLivingParents()
は常に をスローします。NullPointerException
mother
father
つまり、Javaでは、すべてのクラスが何らかのコンストラクターによって初期化される必要があります。クラスに既定のコンストラクターがない場合、オブジェクトを初期化するには、他のコンストラクターのいずれかを呼び出す必要があります。
class Parent
{
Parent(int x) {}
}
class Child extends Parent
{
Child(){} // will not compile.
}
super()
コンパイラはコンストラクターの最初の行として呼び出そうとしChild()
ますが、親には引数なしのコンストラクターがありません。したがって、この場合super(5)
、たとえば を呼び出して明示的に行う必要があります。