1

Javaは多重継承を許可していません。つまり、クラスは2つのクラスから継承できません。これは、共通点がないため、同じ継承パス上にないことを意味します。ただし、これらのクラスがクラスの直接スーパークラスのスーパークラスである場合、クラスはより多くのクラスから継承できます。しかし、クラスはこれらのクラスから間接的に継承します。つまり、これらの上位のスーパークラスからは何も「認識」されません。コンストラクターを検討するときに混乱しました(コンストラクターでsuper()を使用)。たとえば、次のクラスがある場合:

public class A {
    public A() { 
      .... 
    }
}

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

public class C extends B {
    public C() {
      super();
      ....
   }
}

クラスCのコンストラクターは、最初にsuper()を使用してクラスBのコンストラクターを呼び出します。これが発生すると、Bのコンストラクター自体が最初にAのコンストラクターを呼び出します(super()を使用)が、CのコンストラクターはAのコンストラクターについて何も知りませんよね?つまり、継承は直接のスーパークラス(継承階層の最初の(最も近い)クラス)からのみです。これが私の質問です。super()では、継承階層に他のクラスがいくつあっても、直接スーパークラスのコンストラクターのみを意味します。そして、これはコンストラクターだけでなく、すべてのメソッドとインスタンス変数に適用されます。

よろしく

4

5 に答える 5

4

直接の基本クラスでコンストラクターを呼び出す必要があります。これはすることができます

public class A {
     public A() { 
      .... 
     }
    public A(String foo) { 
      .... 
    }
}

public class B extends A {
    public B() {
        super();
        .. or ..
        super("ThisIsAB")
    }
}

public class C extends B {
    public C() {
      super();
      ....
   }
}

したがって、コンストラクターの場合、中間基本クラスの構築を回避することはできませんが、使用するコンストラクターを選択できます。引数なしのコンストラクターしかない場合は、super への暗黙の呼び出しですべて処理されます。複数のコンストラクターを使用すると、より多くの選択肢があります。

super は、任意の基本クラスの非プライベート変数またはメソッドを参照できます。したがって、メソッドと変数は、この点でコンストラクターと同じではありません。

于 2009-01-06T20:37:51.503 に答える
4

中間 ctor の呼び出しを避けることができたとしても、そうしたくないでしょう。それは、最下位の派生クラスによってアクセスされる可能性のある中間クラスの部分が初期化されていないことを意味するからです。恐ろしい効果に。

しかし、多重継承を行うために Java をだまそうとしているように感じます。それは悪いことです。代わりに、インターフェースを使用してJavaで行うことができます

class B extends A implements C {
    // ... implement C methods here
}

または集約を使用して

class B extends A {
    private C c;
}
于 2009-01-06T20:49:57.733 に答える
3

すべての親のコンストラクターが呼び出されます。実際、B は A を拡張しているため、C は深く A について知っています。たとえば、クラス A にメソッド foo() が含まれている場合、C から foo() を呼び出すことができます。

したがって、あなたの例から、C は B からコンストラクターを呼び出し、B からコンストラクターを呼び出します。さらに、A はクラス Object からも拡張されます。したがって、クラス Object のコンストラクターも呼び出されます。

さらに、super() への呼び出しを追加する必要はありません。親のコンストラクターの呼び出しがない場合は、super が暗黙的に呼び出されます。

于 2009-01-06T20:39:26.867 に答える
2

あなたが言うように、CのコンストラクターはAのコンストラクターを呼び出すBのコンストラクターを呼び出します。Cオブジェクトで任意の「A」メソッドを呼び出すことができ、CオブジェクトはAの非プライベートフィールドを見ることができます。

CでAのメソッド「foo」をオーバーライドしても、Bもオーバーライドしないと仮定すると、「super.foo()」を使用してAバージョンを取得できます。

于 2009-01-06T20:33:20.623 に答える
1

C が知る限り、C で上書きされないものはすべて B に含まれています。たとえその下にクラス A が実装されていたとしてもです。

public class A {
   public A() {
   }

   public void aMethod() {
   }
}

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

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

   public void doWork() {
     super.aMethod();
   }
}

したがって、この場合、C のコンストラクターで super() を呼び出すと、A のコンストラクターではなく B のコンストラクターが直接呼び出されますが、A は aMethod() の実装を処理します。

于 2009-01-06T20:44:17.073 に答える