2011-11-03 4 views
19

I.e.次の「循環依存」はなぜできないのですか?Javaが内部インターフェイスの継承を禁止するのはなぜですか?

public class Something implements Behavior { 
    public interface Behavior { 
     // ... 
    } 
} 

インターフェイスは外部クラスを参照しないため、これは許可する必要があります。しかし、コンパイラはクラス外のインタフェースを定義するように強制しています。この動作について論理的な説明はありますか?

+0

最初にクラスを定義する必要があるインターフェイスを知るためには、クラスローダーのようなサウンドがまずクラスを読み取る必要があります...クラスローディングの詳細はわかりませんが、かなりわかります。 –

+2

@donneo:コンパイラは「循環依存」について不平を言っているので、内部クラスにどの型が定義されているかはすでに分かっていると思います。それはちょうど私にとっては恣意的な制限のようです。 –

+0

@PhilipK:どのコンパイラを使用していますか? Mine(Oracle JDK 6および7)は、「シンボルを見つけることができません」と不平を言うだけです。それ以外に、ネストされたインターフェイスは実際には技術的な方法で外部クラスに依存していないので、これは合法である可能性があります。 –

答えて

11

関連ルール:

http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.4

クラスTは、いずれかのスーパークラス又はスーパーインターフェースとして拡張またはCの句を実装に記載されている場合にCが直接型Tに依存スーパークラス名またはスーパーインターフェース名の修飾子として使用できます。

http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.1.3

Tは、に記載されているスーパーインターフェースとして、またはスーパーインタフェース名内の修飾子としてIのいずれかの句を拡張する場合、私は直接型Tに依存するインターフェース。したがって

A extends|implements B.C

場合、AはCBの両方に依存します。 Specは循環依存を禁止します。

Bを依存関係に含める動機は不明です。あなたが言及したように、B.CがトップレベルC2に昇格されている場合は、型システムに関する限り、それほど違いはありません。なぜA extends C2はOKですが、A extends B.Cではないのですか?与えられたネストされたタイプB.CBの内容にアクセスしましたが、A extends B.Cが面倒なものは何も見つかりませんでした。

唯一の問題は、Cが内部クラスの場合です。 "enclosing instance"という循環依存があるので、B=A,A extends A.Cを禁止する必要があるとします。それはおそらく本当の動機です。内側のクラスを継承することから外側のクラスを禁止することです。実際のルールはより単純であり、とにかく非内部クラスであっても意味があるので、より一般化されています。

10

あなたがコンパイラだとします。

クラス「Something」を作成すると言っています。 このクラスはビヘイビアを実装しています... 何かがまだ登録されていないため、動作がまだ存在しません...

問題を理解していますか?

物を含むボックスとしてのクラスを参照してください。行動はボックスの中に含まれています。しかし、何かが存在しません。

+3

質問がC++に関するものであれば、これは有効な答えです。 –

+1

はい、しかし行動はインターフェースなので、何かの作成に依存しません。 –

+0

はい、そのインターフェイスがSomethingの一部であるためです。行動を参照する前に何かが存在する必要がありますが、行動を参照する必要があります。 –

0

言語仕様で禁止されているという単純な事実で十分です。

私は考えることができいくつかの理由:それは有用ではない

  • これを使用する理由が何であれ、より良い選択肢があるはずです。

  • 子クラスは基本クラスを拡張する必要があります。なぜ、子クラス内に基本クラスを宣言するのですか?

  • インナークラスを拡張する独立したクラスを持つことは、直感的ではありません。スペックで

+0

コールバックインタフェースを別のクラスに渡す必要がある場合に便利です。 – ismailarilik

関連する問題