1

Fooインターフェイスを定義および実装する次のクラスを検討してください。

public class MyClass {

    public Foo getFoo() {
        return new FooImpl();
    }

    public void fooMethod(Foo foo) {
        final fooImpl = (FooImpl) foo;
        fooImpl.hiddenMethod();
    }

    public interface Foo {
        void doSomething();
    }

    private class FooImpl implements Foo {
        public void doSomething();

        void hiddenMethod() {
        }
    }
}

外部クラスは、オブジェクトMyClass.getFoo()を取得するために呼び出し、Fooそれを に戻す場合がありますfooMethod()。package-private method を呼び出すことができるように、 の実装とキャストをfooMethod()想定しています。FooImplFooFooFooImplhiddenMethod()

Foo私の質問は、私は へのキャストに夢中ではないということですFooImpl。同じことを行うために使用できる別のパターンはありますか?

前もって感謝します...

4

3 に答える 3

4

ここでの問題は、カプセル化の原則に暗黙のうちに違反していることです。クラスに実装に依存するメソッドがあり、したがって Foo インターフェイスの一部ではありません。これは OO の原則に違反しています。このキャストは氷山の一角にすぎません。呼び出したいメソッドを持たない新しい Foo 実装クラスを設計したい場合はどうしますか?

Foo インターフェイスからのみメソッドを呼び出してこれを実現できるように、コードを再設計する必要があります。

于 2014-04-10T18:19:07.203 に答える
1

インターフェイスにhiddenMethodメソッドを追加できますFoo

public interface Foo {
    ...   
    void hiddenMethod();
}

インターフェイスはサポートされている操作のコントラクトであるため、オブジェクトをキャストしてインターフェイスの外部のメソッドにアクセスする必要はありません (すべきではありませんか?)。

于 2014-04-10T18:17:47.007 に答える
0

あなたは落ち込む必要があります。

このようにしてください

public void fooMethod(Foo foo) {
   if(foo instanceof FooImpl){
      final FooImpl fooImpl = (FooImpl) foo;
      fooImpl.hiddenMethod();
   }
}

スーパータイプは、明示的なダウンキャストなしではダウンキャストできません。instanceof演算子を使用してダウンキャストする前に、必ず確認してください。


- 編集 -

キャストを避けたい場合は、もう 1 つ実行します。インターフェイスも追加hiddenMethod()します。Foo

public interface Foo {
    void doSomething();
    void hiddenMethod();
}
于 2014-04-10T18:13:32.507 に答える