なぜthis()
とsuper()
の両方をコンストラクターで一緒に使用できないのですか?
そのようなものを組み込む理由は何ですか?
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()
は回避しませんが、それらを回避します。
super()
とthis()
には違いがあります。
super()
-は基本クラスコンストラクターを呼び出しますが、this()
-は、現在のクラスコンストラクターを呼び出します。
this()
とsuper()
はどちらもコンストラクター呼び出しです。
コンストラクター呼び出しは常に最初のステートメントでなければなりません。したがって、最初のステートメントとして2つのステートメントを使用することはできません。したがって、super()
を呼び出すか、コンストラクターからthis()
を呼び出すことができますが、両方はできません。
this()
とsuper()
は両方ともコンストラクター呼び出しであり、コンストラクター呼び出しはコンストラクターの最初の(そして最初の)呼び出しでなければなりません。そうでない場合、単一のオブジェクトをインスタンス化するときに、Object
コンストラクターが複数回呼び出されます。
そして、使用しているコンストラクターの最初の行で宣言する必要があるという条件が両方にあります。 最初の行には1つしか記述できないため、単一のコンストラクターで両方を使用できない理由です。
意味をなさないからです。コンストラクターは、this()
またはsuper()
を呼び出す必要があります(暗黙的または明示的に)。 this()
は、以前と同様にthis()
またはsuper()
などを呼び出す必要がある別のコンストラクターを呼び出します。したがって、this()
とsuper()
の両方を呼び出したコンストラクターは、最終的にsuper()
を2回呼び出します。
コンストラクタでthis()
とsuper()
を一緒に使用すると、コンパイル時エラーが発生するためです。 this()
とsuper()
は最初の実行可能ステートメントでなければならないためです。 this()
を最初に記述すると、super()
は2番目のステートメントになり、その逆も同様です。そのため、this()
とsuper()
を一緒に使用することはできません。
以下の例を比較してください。クラス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());
}
}
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);
}
}