Javaのデフォルトのコンストラクターと継承について質問があります。
一般に、クラスを作成し、コンストラクタを含めない場合、Javaは、クラスのすべてのインスタンス変数を初期化するデフォルトのコンストラクタ(パラメータなしのコンストラクタ)を自動的に提供します。 )いくつかのデフォルト値(0、null、またはfalse)を使用しますが、いくつかのパラメーターを使用してコンストラクターを作成し、デフォルトのコンストラクターを作成しない場合、Javaは提供しません私の質問は、他のクラスから継承するクラスの場合です-パラメータを指定してコンストラクターを作成し、デフォルトのコンストラクターを含めない場合、スーパークラスのデフォルトのコンストラクターを継承しますかクラス?
コンストラクタを作成しない場合、- デフォルトの空のコンストラクタが自動的に作成されます 。
コンストラクターが最初のステートメントとして明示的にスーパーまたはこのコンストラクターを呼び出さない場合、 super()への呼び出しが自動的に追加されます 。
常に。
コンストラクターは継承されません。
また、フィールドの初期化は、デフォルトのコンストラクターではなく、仮想マシンによって行われます。デフォルトコンストラクターはスーパークラスのデフォルトコンストラクターを呼び出すだけで、Objectのデフォルトコンストラクターは空です。この設計の良い点は、初期化されていないフィールドにアクセスする方法がないことです。
Super(...)を使用しない限り、コンストラクターはその親の空のコンストラクターを呼び出します。注:これは、Objectを拡張するクラスも含め、すべてのクラスでこれを行います。
これは継承ではなく、サブクラスは同じ引数を持つ同じコンストラクターを取得しません。ただし、スーパークラスのコンストラクターの1つを呼び出すコンストラクターを追加できます。
基本的なルールは、コンストラクターの呼び出し(または呼び出し)が、JVMが実行する必要がある最初のステートメントである必要があることです。
そのため、パラメーター化されたコンストラクターのみを持ち、デフォルトコンストラクターを持たないスーパークラスがあり、基本クラスがスーパークラスのパラメーター化されたコンストラクターを明示的に呼び出さない場合、JVMはsuper()を提供します。スーパークラスのデフォルトコンストラクターがないためエラーをスローする呼び出し。したがって、スーパークラスにデフォルトコンストラクターを提供するか、基本クラスコンストラクターでスーパークラスのパラメーター化されたコンストラクターを明示的に呼び出します。明示的な呼び出しを行うと、JVMはわざわざsuper();という行を入れません。コンストラクターの呼び出しはメソッドの最初のステートメントである必要がありますが、これは発生しません(明示的な呼び出しのため)。
Java Language Specificationのセクション8.8.9で、何が起こっているかを詳しく説明しています。
クラスにコンストラクター宣言が含まれていない場合、デフォルトのコンストラクターが暗黙的に宣言されます。最上位クラス、メンバークラス、またはローカルクラスのデフォルトコンストラクターの形式は次のとおりです。
- デフォルトのコンストラクタは、クラスと同じアクセシビリティを持っています(§6.6)。
- デフォルトコンストラクターは、非プライベートインナーメンバクラスを除き、正式なパラメーターを持ちません。デフォルトコンストラクターは、クラスの即時囲いインスタンスを表す1つの正式なパラメーターを暗黙的に宣言します(§8.8.1、§15.9.2、§15.9.3 )。
- デフォルトのコンストラクターにはthrows句はありません。
- 宣言されているクラスが原始クラスObjectである場合、デフォルトのコンストラクターには空のボディがあります。それ以外の場合、デフォルトのコンストラクターは、引数なしでスーパークラスコンストラクターを呼び出すだけです。
ここでは継承が行われていないことがわかります。それは、暗黙的に宣言されたデフォルトコンストラクターを持つ「コンパイラーマジック」だけです。また、仕様には、クラスにコンストラクターがまったくない場合にのみデフォルトコンストラクターが追加されることが明確になっています。つまり、質問に対する答えは「no」です。クラスにコンストラクターを渡したら、そのデフォルトコンストラクターへのアクセススーパークラスは失われます。
コンストラクタを指定すると、Javaはデフォルトの空のコンストラクタを生成しません。そのため、派生クラスはコンストラクタを呼び出すことしかできません。
デフォルトのコンストラクターは、プライベート変数をデフォルト値に初期化しません。証拠は、デフォルトコンストラクターを持たず、プライベートメンバーをデフォルト値に初期化するクラスを作成できることです。以下に例を示します。
public class Test {
public String s;
public int i;
public Test(String s, int i) {
this.s = s;
this.i = i;
}
public Test(boolean b) {
// Empty on purpose!
}
public String toString() {
return "Test (s = " + this.s + ", i = " + this.i + ")";
}
public static void main (String [] args) {
Test test_empty = new Test(true);
Test test_full = new Test("string", 42);
System.out.println("Test empty:" + test_empty);
System.out.println("Test full:" + test_full);
}
}
あなたの質問への答えは非常に簡単です。暗黙的に(非表示)、コンストラクターの最初のステートメントは 'super();'です。つまり、明示的に「this();」、「this(int)」、「this(String)」、「super(int)」、「super(String) ) 'など' this(); '現在のクラスのコンストラクタです。
親指のルールは、サブクラスが基本クラスから任意のコンストラクターを呼び出す必要があるということです。デフォルトのconstがない場合は、サブクラスから既存のconstを呼び出します。そうでない場合は、基本クラスに空のconstを実装して、コンパイルの問題を回避します
コンストラクタを作成しない場合Javaはデフォルトのコンストラクタを自動的に作成します。しかし、引数を持つ1つ以上のカスタムコンストラクタを作成する場合、Javaは作成しません1つ以上のコンストラクターを作成し、コンストラクター引数なしでオブジェクトを作成する場合、空のコンストラクターを宣言する必要があります。
コンパイル時にエラーが発生します...コンパイラはスーパークラスのデフォルトのコンストラクタを探し、そこになければ...エラーが発生し、プログラムはコンパイルされません...
サブクラスのコンストラクターは、親クラスの引数なしのコンストラクター(またはデフォルトコンストラクター)を呼び出します。親クラスでパラメータ化されたコンストラクタを定義する場合、スーパーキーワードを使用して親クラスコンストラクタを明示的に呼び出す必要があります。そうでない場合、コンパイルエラーが発生します。
class Alpha
{
Alpha(int s, int p)
{
System.out.println("base");
}
}
public class SubAlpha extends Alpha
{
SubAlpha()
{
System.out.println("derived");
}
public static void main(String[] args)
{
new SubAlpha();
}
}
上記のコードは、コンパイルエラーを示します。
prog.Java:13: error: constructor Alpha in class Alpha cannot be applied to given types;
{
^
required: int,int
found: no arguments
reason: actual and formal argument lists differ in length
1 error
上記のエラーは、親クラスに引数コンストラクタ/デフォルトコンストラクタがないため、サブクラスからパラメータ化されたコンストラクタを呼び出していないために発生しました。
これを解決するには、次のようにパラメーター化されたコンストラクターを呼び出します。
class Alpha
{
Alpha(int s, int p)
{
System.out.println("base");
}
}
public class SubAlpha extends Alpha
{
SubAlpha()
{
super(4, 5); // calling the parameterized constructor of parent class
System.out.println("derived");
}
public static void main(String[] args)
{
new SubAlpha();
}
}
出力
base
derived
または
次のように、親クラスに引数なしのコンストラクタを定義します。
class Alpha
{
Alpha(){
}
Alpha(int s, int p)
{
System.out.println("base");
}
}
public class SubAlpha extends Alpha
{
SubAlpha()
{
System.out.println("derived");
}
public static void main(String[] args)
{
new SubAlpha();
}
}
出力
derived