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(). fooMethod()期望FooImpl实现Foo并强制转换Foo为,FooImpl因此它可以调用包私有方法hiddenMethod()

我的问题是,我并不热衷于投射FooFooImpl. 我可以用另一种模式来做同样的事情吗?

提前致谢...

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运算符向下转换之前检查它。


- 编辑 -

如果你想避免铸造,再做一件事。也加入界面hiddenMethod()Foo

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