これは、コンストラクターの親クラスと子クラスの this(...)
違いです。super(...)
まず、この包括的なテスト プログラムを作成して実行しました。構築時に間違っていると証明される主張をするのは嫌いです...
public class Philosopher {
Philosopher(String s) {
System.out.println(s);
System.out.print("from Philosopher(String s){System.out.println(s);}... ");
}
Philosopher() {
this("whatev... ");
System.out.print("from Philosopher(){this(\"whatev... \");}... ");
}
}
class Kant extends Philosopher {
Kant(String s) {
System.out.println(s);
System.out.print("from Kant(String s){System.out.println(s);}... ");
}
Kant() {
this("whatev... ");
System.out.println("from Kant(){this(\"whatev... \");}... ");
}
Kant(int i) {
super("whatev... ");
System.out.println("from Kant(int i){super(\"whatev... \");}... ");
}
public static void main(String[] args) {
String s = "String \"s\" InMain";
System.out.print("\n\n new Philosopher(s); produces:\n");
new Philosopher(s);
System.out.print("\n\n new Philosopher(); produces:\n");
new Philosopher();
System.out.print("\n\n new Kant(s); produces:\n");
new Kant(s);
System.out.print("\n\n new Kant(); produces:\n");
new Kant();
System.out.print("\n\n new Kant(69); produces:\n");
new Kant(69);
}
}
注釈付き出力
実行すると、この出力が得られます。出力の各行に自分のコメントを散りばめています。
new Philosopher(s);` produces
String "s" InMain
from Philosopher(String s){System.out.println(s);}...
this()
ここで驚くことではありませんが、またはへの参照を行わないスーパークラスのコンストラクターを呼び出すと、スーパークラスsuper()
のコンストラクターのみが実行されます。
new Philosopher(); produces:
whatev...
from Philosopher(String s){System.out.println(s);}... from Philosopher(){this("whatev... ");}...
それほど驚くことではありません。 Philosopher()
を使用this("whatev...")
し、コンストラクターthis()
を参照します。Philosopher(String s)
したがって、この構造ではPhilosopher()
とPhilosopher(String s)
get の両方が呼び出されます。
new Kant(s); produces:
whatev...
from Philosopher(String s){System.out.println(s);}... from Philosopher(){this("whatev... ");}... String "s" InMain
from Kant(String s){System.out.println(s);}...
これは私を驚かせました!単純なコンストラクターはorを使用Kant(String s)
して何も呼び出しませんが、. 親クラスのコンストラクターを明示的に呼び出さないすべてのサブクラスのコンストラクターは、引数なしの親クラスのコンストラクターを魔法のように呼び出します!this()
super()
Kant
したがって、Kant
a を参照しないコンストラクターは、最初の行super
であるかのように動作します。super();
したがって、親から子への構造の連続性があります。
new Kant(); produces:
whatev...
from Philosopher(String s){System.out.println(s);}... from Philosopher(){this("whatev... ");}... whatev...
from Kant(String s){System.out.println(s);}... from Kant(){this("whatev... ");}...
Kant()
はありますthis
が、ありませんsuper
。したがって、Java は魔法のようにコンストラクターに super()
権利があるかのように振る舞います。Kant()
new Kant(69); produces:
whatev...
from Philosopher(String s){System.out.println(s);}... from Kant(int i){super("whatev... ");}...
そのKant(int i)
ため、DOES には親クラス コンストラクターへの明示的な参照があります。したがって、その出力は比較的単純です。直接参照したため、暗黙の親コンストラクターの呼び出しによって得られ Philosopher(String s)
た余分な迂回路を使用しません。Philosopher()
結論
子クラスのコンストラクターは、常に親クラスのコンストラクターを呼び出します。呼び出す親クラス コンストラクターを指定しない場合、子クラス コンストラクター内の他のコードより前に、引数なしのコンストラクターが呼び出されます。呼び出す親クラスのコンストラクターを指定すると、より細かく制御できます。
this
andを使用するコンストラクターsuper
は、かなりの量を連鎖させることができます。一見単純なnew Kant()
オブジェクトの構築中に、最大 4 つのコンストラクターがアクセスされます。
ここまで読んでくれたあなたには、何かのご褒美が必要です!私に賛成票を投じてください...