web-dev-qa-db-ja.com

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

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

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

31
Babloo

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()を使用できた場合、次のような結果になります。

注意:これは、何がうまくいかないかを示すことを意味します、あなたがそれを許可された場合-幸いなことに't)

_     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()は回避しませんが、それらを回避します。

35
Thomas

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

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

this()super()はどちらもコンストラクター呼び出しです。
コンストラクター呼び出しは常に最初のステートメントでなければなりません。したがって、最初のステートメントとして2つのステートメントを使用することはできません。したがって、super()を呼び出すか、コンストラクターからthis()を呼び出すことができますが、両方はできません。

8
Sachin Mhetre

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

4
MByD
  • this()キーワードをコンストラクタチェーンで使用して、同じクラスのコンストラクタにアクセスします
  • 継承で直接の親クラスのコンストラクターにアクセスする場合は、super()キーワードを使用します。

そして、使用しているコンストラクターの最初の行で宣言する必要があるという条件が両方にあります。 最初の行には1つしか記述できないため、単一のコンストラクターで両方を使用できない理由です。

2
Varun Vashista

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

1
user207421

コンストラクタでthis()super()を一緒に使用すると、コンパイル時エラーが発生するためです。 this()super()は最初の実行可能ステートメントでなければならないためです。 this()を最初に記述すると、super()は2番目のステートメントになり、その逆も同様です。そのため、this()super()を一緒に使用することはできません。

0
Harshita Yadav

以下の例を比較してください。クラスFirstChildは、最初のコンストラクターから2番目のコンストラクターを呼び出すことはsuper()を呼び出す必要がないため、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());
    }
}
0

this()とsuper()、どちらもコンストラクターであるため、最初のステートメントである必要があります。しかし、プログラムで両方を使用できます。

this():これは、同じクラスDefaultまたはParametrized Constructorを呼び出すために使用されます。

super():スーパークラスまたは親クラスのデフォルトまたはパラメータ化されたコンストラクタを直接呼び出すために使用されます。

//Super Class
    public class SuperConstructor {
    SuperConstructor(){
        this(10);
        System.out.println("Super DC");
    }

    SuperConstructor(int a){
        this(10,20);
        System.out.println("Suer SPC with Iteger");
    }

    SuperConstructor(int i,int j){
        System.out.println("Super with  DPC with Iteger and Integer");
    }
}


//subclass
    public class ThisConstructor extends SuperConstructor{  
    ThisConstructor(){
        this(10,20);
        System.out.println("Subcalss DC ");//DC Default Constructor
    }

    ThisConstructor(int i){
        super(i);       
        System.out.println("Subcalss  SPC with Iteger");//SPC Single Parameterized Constructor
    }

    ThisConstructor(int i, String s){
        this();
        System.out.println("Subcalss  DPC with Iteger and String");//DPC double Parameterized Constructor
    }

    ThisConstructor(int i,int age){
        super(i,age);
        System.out.println("Subcalss  DPC with Iteger and Integer");
    }

    public static void main(String []k){
        System.out.println("=================Frist time Calling ==========================\n");
        ThisConstructor t = new ThisConstructor(1);


        System.out.println("=================Second time Calling ==========================\n");
        ThisConstructor t1 = new ThisConstructor(1,2);
    }
}
0