3

クラス a がクラス b を拡張し、クラス b がクラス c を拡張する場合aはcb両方から継承ますか? もしそうなら、2つの間の競合の場合、エラーがありますか、それとも別のものをオーバーライドしますか?

質問のタイトルが不適切な場合は、質問の名前を変更してください。

編集:競合とは、次のようなものです。

class c {
   int foo;
   //Stuff
}
class b extends c {
   String foo;
   //Stuff
}
class a extends b {
   //Stuff
}

文字列ですかa.foo、それともintですか?

別の編集: したがって、私が収集したものから、ここでの継承は CSS に少し似ています。ルールが設定されているほど、優先度が高くなります (たとえば、インライン スタイルはスタイルシートをオーバーライドします)。それはこれを考える良い方法ですか、それとも大きく異なりますか?

4

6 に答える 6

5

bと の両方に何かが存在する場合は、c使用aする方を継承bします。

于 2012-06-24T13:50:34.363 に答える
4

はい、a は b と c から継承します。b のメソッドのオーバーライドは a に対して有効であるため、この状況でどのように競合が発生するのかわかりません。多重継承による競合から生じるひし形の問題を考えているかもしれませんが、それは 2 つの異なる親を持つ場合であり、一方の親がもう一方の親である 2 つの親ではありません。

2 つのメソッドが同じ署名を持っているが、1 つのメソッドのルールが別のメソッドのルールと一致しないという、インターフェイスで「ソフト」ダイヤモンド問題に遭遇する可能性があります。どちらのインターフェイスにもメソッドの実装がないため、(私が知っている) コンパイルの問題はなく、単なる論理的な問題です。

編集ああ、変数 に関するあなたの編集を見ましたが、それに対するジンパンジーの反応に同意します。テストするのは確かに簡単です:

public class Test3 {
   public static void main(String[] args) {
      MyA myA = new MyA();
      System.out.println("foo := " + myA.foo);
   }
}

class MyC {
   public int foo = 3;
   //Stuff
}
class MyB extends MyC {
   public String foo = "foo";
   //Stuff
}

class MyA extends MyB {

}
于 2012-06-24T13:46:16.000 に答える
2

Java ではメソッドのみがオーバーライドの対象となります。それ以外はすべて継承されるだけで、名前空間の衝突の問題だけがありますが、すべてにアクセスできます。あなたの例では、両方fooにアクセスできますA(クラス名を修正して、強力なJava命名規則に準拠させました):

class C {
  int foo;
  //Stuff
}
class B extends C {
  String foo;
  //Stuff
}
class A extends B {
  String x = ((B)this).foo;
  int i = ((C)this).foo;
}
于 2012-06-24T14:21:53.450 に答える
2

This answerにははるかに良い例があり、この種のことを行うことは悪い習慣と見なされることを指摘しています。(たとえば、Eclipse では警告が表示されます。) コードを少し拡張します。

class c {
   int foo = 42;
   //Stuff
}
class b extends c {
   String foo = "foostr";
   //Stuff
}
class a extends b {
   //Stuff
}
class Main{
   public static void main(String[] args){
      a mya = new a();
      System.out.println(mya.foo);
   }
}

java Mainプリントを実行していfoostrます。

于 2012-06-24T13:58:30.490 に答える
2

さて、ルールは次のとおりです。

  1. すべてのサブクラスは、その階層の最も近いものを継承します。したがって、 aはbからすべてを取得します。継承スタックにあるものはすべてbまで利用できるためです。bは、継承階層からすでにすべてを継承しているためです。

  2. 次に、bが何か (インスタンス変数/メソッド) をオーバーライドすると、 aにはオーバーライドされたバージョンが表示されます。したがって、あなたの場合、 aは String foo を取得します。

于 2012-06-24T14:04:03.693 に答える
1

はい、c と b の両方から継承しています。競合を防止/回避するために、Java は単一の階層モデルをサポートします (複数クラスの継承モデルを許可する C++ などの他の OOP 言語とは異なります)。

于 2012-06-24T13:46:36.907 に答える