つまり、なぜ次の「循環依存」が不可能なのですか?
public class Something implements Behavior {
public interface Behavior {
// ...
}
}
インターフェイスは外部クラスを参照しないため、これを許可する必要があります。ただし、コンパイラは、クラスの外部でこれらのインターフェイスを定義するように強制しています。この動作の論理的な説明はありますか?
つまり、なぜ次の「循環依存」が不可能なのですか?
public class Something implements Behavior {
public interface Behavior {
// ...
}
}
インターフェイスは外部クラスを参照しないため、これを許可する必要があります。ただし、コンパイラは、クラスの外部でこれらのインターフェイスを定義するように強制しています。この動作の論理的な説明はありますか?
仕様の関連ルール:
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.4
クラスCは、Tがスーパークラスまたはスーパーインターフェースとして、あるいはスーパークラスまたはスーパーインターフェース名の修飾子としてCのextendsまたはimplements節で言及されている場合、タイプTに直接依存します。
http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.1.3
インターフェイスIは、Tがスーパーインターフェイスまたはスーパーインターフェイス名内の修飾子としてIのextends句で言及されている場合、タイプTに直接依存します。
したがって、の場合、Aはとの両方にA extends|implements B.C
依存します。その後、Specは循環依存を禁止します。C
B
依存関係に含める動機B
は不明です。おっしゃるように、B.C
トップレベルに昇格した場合C2
、型システムに関してはそれほど違いはありませんが、なぜA extends C2
大丈夫なのA extends B.C
ですか?ネストされたタイプを許可すると、のコンテンツB.C
へのアクセス権がある程度付与されますB
が、仕様に問題を引き起こすものは見つかりませんA extends B.C
。
唯一の問題は、C
が内部クラスである場合です。「インスタンスを囲む」という循環依存関係があるため、を禁止B=A
する必要があるとします。A extends A.C
それがおそらく本当の動機です-外部クラスが内部クラスを継承することを禁止することです。実際のルールはより一般化されています。なぜなら、それらはより単純であり、非内部クラスに対してもとにかく理にかなっているからです。
あなたがコンパイラだと想像してみてください。
クラスSomethingを作成するように言っています。このクラスはBehaviorを実装しています...しかし、何かがまだ登録されていないため、Behaviorはまだ存在していません...
問題を理解していますか?
物を含むボックスとしてのクラスを参照してください。動作はボックスSomethingに含まれています。しかし、何かが存在しません。
言語仕様がそれを禁止しているという単純な事実で十分なはずです。
私が考えることができるいくつかの理由:
それは役に立たないでしょう。
あなたがこれを使いたいと思うかもしれないどんな理由でも、私はより良いオプションが存在すると確信しています。
子クラスは基本クラスを拡張する必要があるのに、なぜそれ自体の子の中で基本クラスを宣言するのでしょうか。
別のクラスで内部クラスを拡張するのは直感に反します。