考虑以下定义和实现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()
。
我的问题是,我对Foo
FooImpl
的投射并不感到骄傲。还有其他模式可以用来做同样的事情吗?
提前致谢...
答案 0 :(得分:3)
这里的问题是你隐含地违反了封装原则。您的类中有一个方法,它取决于实现,因此不属于Foo接口。这违反了OO校长,这个演员阵容只是冰山一角。如果您想设计一个没有想要调用的方法的新Foo实现类,该怎么办?
您应该重新设计代码,以便只能从Foo界面实现此调用方法。
答案 1 :(得分:1)
您可以在hiddenMethod
界面
Foo
方法
public interface Foo {
...
void hiddenMethod();
}
由于接口是受支持操作的契约,因此您不需要(不应该)将对象转换为访问接口外部的方法
答案 2 :(得分: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();
}