0

私はコンストラクターのオーバーロードに関する研究を行っていました。以下は私のコードです

class Philosopher {
    Philosopher(String s) {
        System.out.print(s + " ");
    }
}

public class Kant extends Philosopher {
    // insert code here
    Kant() {
        this("Bart"); //constructor overloading 
        //super("Bart"); //-->can also write this 
    }

    Kant(String s) {
        super(s);
    }

    public static void main(String[] args) {
        new Kant("Homer"); 
        new Kant();
    }
}

今私の質問は、 this("Bart"); を書いているデフォルトのコンストラクター内のクラス Kant です。クラス自体内で別のコンストラクターを呼び出していますが、 super("Bart") を使用できません。同じ機能も実行します。アドバイスしてください。

4

3 に答える 3

4

この特定のケースでは、はい、使用できますsuper("Bart")-両方のケースでこれがコンストラクターチェーンであるというわけではありません。オーバーロードは、複数のコンストラクターを持つだけです。

ただし、通常は、1 つのクラス内のすべてのコンストラクターをそのクラスの "マスター" コンストラクター (呼び出しを持つ唯一のコンストラクター) にチェーンすることをお勧めしsuper(...)ます。そうすれば、そのコンストラクターに配置したロジックは、どのコンストラクターが呼び出されても実行されます。この場合、コンストラクターに他のロジックがないため関係ありませんが、通常はそうではありません。

于 2012-05-01T06:50:58.927 に答える
0

これは、コンストラクターの親クラスと子クラスの 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

したがって、Kanta を参照しないコンストラクターは、最初の行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()

結論

子クラスのコンストラクターは、常に親クラスのコンストラクターを呼び出します。呼び出す親クラス コンストラクターを指定しない場合、子クラス コンストラクター内の他のコードより前に、引数なしのコンストラクターが呼び出されます。呼び出す親クラスのコンストラクターを指定すると、より細かく制御できます。

thisandを使用するコンストラクターsuperは、かなりの量を連鎖させることができます。一見単純なnew Kant()オブジェクトの構築中に、最大 4 つのコンストラクターがアクセスされます。

ここまで読んでくれたあなたには、何かのご褒美が必要です!私に賛成票を投じてください...

于 2012-05-01T23:44:49.820 に答える
0

あなたの場合、あなたも電話することができますsuper("Bart")

Kant(String s)ただし、コンストラクターが追加のコードを呼び出す場合を考えてみ ましょう。その場合super("Bart")、実行されないためKant(String s)、そのコンストラクター内の追加のコードは呼び出されません。

于 2012-05-01T06:50:39.467 に答える