40

this()コンストラクターでsuper()両方を一緒に使用できないのはなぜですか?

そのようなものを組み込む理由は何ですか?

4

11 に答える 11

48

this(...)super()スーパーコンストラクターを呼び出すのに対し、同じクラスの別のコンストラクターを呼び出します。コンストラクターにない場合super()、コンパイラーは暗黙的にコンストラクターを追加します。

したがって、両方が許可されている場合、superコンストラクターを 2 回呼び出すことになる可能性があります。

例 (パラメーターの意味を探さないでください):

class A {
  public A() {
    this( false );
  }

  public A(boolean someFlag) {
  }
}

class B extends A {
  public B() {
    super();
  }

  public B( boolean someFlag ) {
    super( someFlag );
  }

  public B ( int someNumber ) {
    this(); //
  }
} 

ここでnew B(5)、次のコンストラクターを呼び出すと、呼び出されます。

     this( false);
A() ---------------> A(false)
^
|
| super(); 
|
|     this();
B() <--------------- B(5)  <--- you start here

更新

使用できた場合、次のような結果になる可能性がthis()あります。super()

(注意: これは、許可されている場合に、何がうまくいかないかを示すことを目的としています - 幸いなことに、そうではありません)

     this( false);
A() ---------------> A(false)
^                    ^
|                    |
| super();           | super( true ); <--- Problem: should the parameter be true or false? 
|                    |
|     this();        |
B() <--------------- B(5)  <--- you start here

ご覧のとおり、A(boolean)コンストラクターがさまざまなパラメーターで呼び出される可能性があるという問題に遭遇し、どちらを使用する必要があるかをどうにかして決定する必要があります。さらに、他のコンストラクター (A()およびB()) には、正しく呼び出されない可能性があるコード (つまり、順不同など) が含まれる可能性がありsuper( true )ますthis()

于 2012-04-30T09:24:46.003 に答える
13

と の間には違いがsuper()ありthis()ます。

super()- 基本クラスのコンストラクターを呼び出しますが、
this()- 現在のクラスのコンストラクターを呼び出します。

this()とはどちらsuper()もコンストラクター呼び出しです。
コンストラクター呼び出しは常に最初のステートメントでなければなりません。したがって、最初のステートメントとしてsuper()orがあります。this()

于 2012-04-30T09:32:04.273 に答える
4

this()とは両方ともsuper()コンストラクター呼び出しであり、コンストラクター呼び出しは、コンストラクターの最初の (そして唯一の) 呼び出しでなければなりません。そうしObjectないと、単一のオブジェクトをインスタンス化するときに、コンストラクターが複数回呼び出されます。

于 2012-04-30T09:24:05.980 に答える
2

意味がないからです。this()コンストラクターはorをsuper()(暗黙的または明示的に)呼び出す必要があります。以前のようにor etcthis()を呼び出す必要がある別のコンストラクターを呼び出します。両方を呼び出したため、最終的に2 回呼び出すコンストラクター。this()super()this()super()super()

于 2012-04-30T10:01:28.833 に答える
0

以下の例を比較してください。クラス FirstChild は、super() を呼び出す必要があるため、最初のコンストラクターから 2 番目のコンストラクターを呼び出すことは除外されるため、2 つのコンストラクターでインスタンス変数名を設定します。

クラス SecondChild には、2 つのパラメーターを取る 3 番目のプライベート コンストラクターが導入されています。最初のパラメーターは supper() に渡され、2 番目のパラメーターは名前の設定に使用されます。最初の 2 つのコンストラクターが 3 番目のコンストラクターを呼び出しています。Super() は 1 回だけ呼び出され、インスタンス変数は 1 つのコンストラクターでのみ設定されます。コードは、同じコンストラクターで super() と this() を呼び出す必要なく、同じ結果を生成します。

class FirstChild extends ConstructorTest{
    private String name = null;
    public FirstChild(){
        super("super text 1");
        //this("Unknown"); //UNCOMMENTED DOES NOT COMPILE
        name = "Unknown";
    }
    public FirstChild(String name){
        super("super text 2");
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

class SecondChild extends ConstructorTest{
    private String name = null;
    public SecondChild(){
        this("super text 1", "Unknown");
    }
    public SecondChild(String name){
        this("super text 2", name);
    }
    private SecondChild(String superStr, String name)
    {
        super(superStr);
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

public class ConstructorTest{
    public ConstructorTest(String str){
        System.out.println("ConstructorTest constructor called with parameter \"" + str + "\"");
    }
    public static void main(String... args)
    {
        System.out.println("Hello from main, FirstChild results:");
        FirstChild fc1 = new FirstChild();
        FirstChild fc2 = new FirstChild("John");
        System.out.println("           child fc1 name: " + fc1.getName());
        System.out.println("           child fc2 name: " + fc2.getName());
        System.out.println("Hello from main, SecondChild results:");
        SecondChild sc1 = new SecondChild();
        SecondChild sc2 = new SecondChild("John");
        System.out.println("           child sc1 name: " + sc1.getName());
        System.out.println("           child sc2 name: " + sc2.getName());
    }
}
于 2016-07-25T08:47:13.487 に答える
0

super() - 直接の親クラス インスタンスを参照します。直接の親クラス メソッドを呼び出すために使用できます。this() - 現在のクラス インスタンスを参照します。現在のクラス メソッドを呼び出すために使用できます。

于 2020-10-13T10:59:08.377 に答える
0

コンストラクター呼び出しはメソッドの最初のステートメントである必要があるため、メソッド内でこれとスーパー コンストラクターの両方を定義すると、次のように競合が発生します。このコンストラクターが最初に呼び出された場合、現在のクラス コンストラクターがチェックされ、現在のクラス コンストラクターに別のメソッド呼び出しまたはステートメントがあるかどうかがチェックされます。したがって、この呼び出しでは、現在のクラスコンストラクター内のすべてのメソッドとステートメントが呼び出されてから、スーパークラスコンストラクターが呼び出され、「コンストラクター呼び出しはメソッドの最初のステートメントでなければならない」というステートメントが拒否されます。

于 2021-06-04T07:30:46.080 に答える