この記事では、Java の基本クラスのコンストラクター呼び出しについて説明します (コード付き)。必要な方は参考にしていただければ幸いです。
『Java プログラミングの思想』の第 7 章に、再利用可能なクラスに関するこのような一節があります。これは熟考する価値があります。サブクラスが親クラスを継承する場合、基本クラスと派生クラス (サブクラス) の 2 つのクラスが関係します。外部から見ると、派生クラスは、基本クラスと同じインターフェイスを備え、おそらく追加のメソッドとフィールドを備えた新しいクラスのように見えます。ただし、継承は基本クラスのインターフェイスをコピーするだけではありません。エクスポートされたクラス オブジェクトを作成すると、そのオブジェクトには基本クラスのサブオブジェクトが含まれます。このサブオブジェクトは、基本クラスで直接作成したオブジェクトと同じです。後者は、基本クラスのサブオブジェクトは外側にありますが、サブオブジェクトは派生クラス オブジェクトの内側にラップされます。
これは非常に重要な問題を引き起こします。また、基本クラスのサブオブジェクトを正しく初期化することも重要です (基本クラスから継承されたメソッドとフィールドをサブクラスで使用する可能性があります)。これを確実に行う唯一の方法は、サブクラス コンストラクターで基本クラス コンストラクターを呼び出して初期化を実行することです。
クラスのコンストラクタを指定しないと、Java がパラメータのないコンストラクタを自動的に呼び出し、Java がそれをエクスポートすることもわかっています。基本クラスのコンストラクターをクラス コンストラクターに呼び出します。次のコードは、この動作メカニズムを示しています。
//: reusing/Cartoon.java // Constructor calls during inheritance. import static net.mindview.util.Print.*; class Art { Art() { print("Art constructor"); } } class Drawing extends Art { Drawing() { print("Drawing constructor"); } } public class Cartoon extends Drawing { public Cartoon() { print("Cartoon constructor"); } public static void main(String[] args) { Cartoon x = new Cartoon(); } } /* Output: Art constructor Drawing constructor Cartoon constructor *///:~
上記のコードの実行結果を観察してください。 Cartoon オブジェクトを作成するとき、その親クラス Drawing のコンストラクターが最初に呼び出され、その親クラスは Art から継承されます。したがって、レイヤーごとと同様に、Art クラスのコンストラクターが再度呼び出されます。親クラスのコンストラクターはコンストラクター内で明示的に呼び出されませんが、Java は自動的に親クラスのコンストラクターを呼び出します。 Cartoon() のコンストラクターを作成しない場合でも、コンパイラーは、基本クラスのコンストラクターを呼び出すデフォルトの引数なしのコンストラクターを合成します。
基本クラスのコンストラクターがすべてパラメーターを持つ場合、コンパイラーはそれを自動的に呼び出さず、キーワード super Base クラス コンストラクターを使用して明示的に呼び出す必要があります。対応するコード例は次のとおりです。
//: reusing/Chess.java // Inheritance, constructors and arguments. import static net.mindview.util.Print.*; class Game { Game(int i) { print("Game constructor"); } } class BoardGame extends Game { BoardGame(int i) { super(i); print("BoardGame constructor"); } } public class Chess extends BoardGame { Chess() { super(11); print("Chess constructor"); } public static void main(String[] args) { Chess x = new Chess(); } } /* Output: Game constructor BoardGame constructor Chess constructor *///:~
上記のコードからわかるように、親クラスのコンストラクターは、サブクラスの Chess コンストラクターで明示的に呼び出して、適切なメソッドを渡す必要があります。パラメーター。さらに、基本クラス コンストラクターの呼び出しは、サブクラス コンストラクターで最初に行う必要があります。
その前に、最初にオブジェクト参照の 初期化問題について説明します。 Java では、クラス内のフィールドが基本型の場合は自動的にゼロに初期化できますが、オブジェクト参照は null に初期化されます。多くの場合、適切な場所で初期化する必要があります。初期化を実行できる場所は次のとおりです。
1. オブジェクトが定義されている場所。 これは、コンストラクターが呼び出される前に常に初期化できることを意味します。
2. クラスのコンストラクター内。 3. これらのオブジェクトが使用される直前のこのメソッドは、遅延初期化と呼ばれます。 上記のポイント 1 を思い出してください。基本クラス コンストラクターの呼び出しシーケンスを確認するために、より複雑な例を見てみましょう。// reusing/Ex7/C7.java // TIJ4 Chapter Reusing, Exercise 7, page 246 /* Modify Exercise 5 so that A and B have constructors with arguments instead * of default constructors. Write a constructor for C and perform all * initialization within C's constructor. */ import static org.greggordon.tools.Print.*; class A { A(char c, int i) { println("A(char, int)");} } class B extends A { B(String s, float f){ super(' ', 0); println("B(String, float)"); } } class C7 extends A { private char c; private int i; C7(char a, int j) { super(a, j); c = a; i = j; } B b = new B("hi", 1f); // will then construct another A and then a B public static void main(String[] args) { C7 c = new C7('b', 2); // will construct an A first } }上記のコード出力: A(char, int)A(char, int)B(String, float)基本クラス コンストラクター、サブクラス コンストラクター、クラス メンバー オブジェクトの初期化の順序に注意してください: 1。クラスのオブジェクトを新規作成するときは、最初にその親クラスのコンストラクターを呼び出します (パラメーターなしまたはパラメーター化できます。システムは自動的にパラメーターなしのものを呼び出します。パラメーターがある場合は自分で指定する必要があります)。上記の C7 の super(a, j)2 など。次に、そのメンバー オブジェクトの初期化ステートメントを実行し、クラス B のコンストラクター (上記の
B b = new B("hi", 1f) など) を呼び出します。B のコンストラクターは、最初に基本クラス A のコンストラクターを呼び出します。
以上がJava基本クラスのコンストラクタ呼び出しの説明(コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。