4

次の循環継承階層はJavaでは許可されていないことを私は知っています。コンパイラはエラーをスローしますが、私が本当に興味を持っているのは、コンパイルが失敗した正確な理由を知ることです。

class A extends B{}
class B extends C{}
class C extends A{}  // this will give you compile time error.

コードを書いた瞬間にコンパイラがエラーをスローする原因は何ですかclass C extends A{}

4

7 に答える 7

12

そのような関係は単に不可能です。無限再帰クラスを定義します。を定義するには、必要があり、class C必要を定義し、必要を定義するclass Aには、開始点に戻ります。これは無限に続くので、コンパイラはこれを行うことができず、論理的な意味もありません。class Aclass Bclass Bclass C

于 2012-12-10T06:39:36.873 に答える
3

単純で非常に実用的な問題があります(他の回答で説明されている論理的な問題を除いて):

クラスはインスタンス化中に初期化する必要があります。これは、Javaでスーパークラスを最初に初期化することによって行われます。サイクルがある場合、初期化コードは継承ラダーを上って、到達しないスーパークラスを初期化しようとします...

したがって、Javaの場合、これは禁止する必要があります。

于 2012-12-10T06:56:33.063 に答える
3

extendsという単語を見てください。Javaでは、子クラスは実際にそのスーパークラスを拡張します。これは、子オブジェクトがそのすべてのスーパーオブジェクトに加えて、いくつかの新しいメンバーといくつかの指定されたメンバーであることを意味します。

では、どうすればよいのでしょうか

  • AはBの拡張です
  • BはCの拡張です
  • CはAの拡張ですか?

拡張は順序関係であると言えます 。A拡張BA<Bを意味し(A <= Bでもない)、あなたの場合はB <Cなので、 CはAより小さくできないことは明らかです。

于 2012-12-10T06:47:01.557 に答える
1

家系図への継承の概念を抽象化してみましょう。本質的に、これは彼らが要約するものです。ここでは逆マッピングスキームを使用するので、CからAへの道を進みます。

  • あなたは母親から特定の属性を継承します。
  • あなたのお母さんはお父さんから特定の属性を継承しています。
  • あなたの祖父は、継承チェーンの中で最高と見なすことができます。

Javaでは、これにより次のようになります。

  • CはBから継承します。
  • BはAから継承します。
  • Aは、継承チェーンの最上位のオブジェクトです。

論理的に極端に言えば、これには多重継承が含まれます。これはJavaでサポートされていない機能ですが、インターフェイスを使用することで軽減できます。

あなたの相続制度が言っていることは、祖父が孫から直接相続するということですが、それは意味がありません。

于 2012-12-10T06:54:29.090 に答える
1

C IS-Aなので 、これらのステートメントに問題を減らすことができますB

class A extends C{}
class C extends A{}

明らかにそれは競合であり、したがってコンパイラはそのエラーを出します。

于 2012-12-10T06:39:05.127 に答える
0

循環継承には2つの例があります
。1。クラスAはAを拡張します{}:-クラスAのメンバーはクラスAにすでに存在するため、これは意味がありません。
2.クラスAはB{}を拡張し、クラスBはA {}を拡張します:-この場合、両方のクラスのメンバーを1つのクラスに記述してから、2つのクラスを記述して相互に拡張することができます。
上記のユースケースは無効であるため、Javaは循環継承をサポートしていません。

于 2016-09-21T10:55:08.477 に答える
0

私は、このスレッドに、まだ述べられていないJava固有の回答を追加すると思いました。Javaでは、すべてのクラスは最終的にクラスから派生する必要がありますObject。そのため、すべてのオブジェクトを問題なくのインスタンスにキャストできますObject。この事実をサポートするために、Java継承チュートリアルには次のように記載されています。

スーパークラスを持たないObjectを除いて、すべてのクラスには1つだけの直接スーパークラス(単一継承)があります。他の明示的なスーパークラスがない場合、すべてのクラスは暗黙的にObjectのサブクラスになります。

クラスは、クラスから派生したクラスなどから派生したクラスから派生したり、最終的に最上位のクラスであるObjectから派生したりすることができます。このようなクラスは、オブジェクトに戻る継承チェーン内のすべてのクラスの子孫であると言われます。

循環継承の依存関係が許可されている場合、およびJavaのクラスには直接スーパークラスが1つだけ必要であるため(上​​記を参照)、循環依存チェーンのクラスのインスタンス(たとえば、クラス、、、AおよびB)はCから継承できません。Object許可されていません。したがって、これらの循環依存オブジェクトはいずれもsとして扱うことができませんでしObjectた。したがって、コンパイラは循環依存を禁止する必要があります。

于 2017-09-14T21:51:25.443 に答える