更好的避免施法的方法?

时间:2012-04-03 18:19:33

标签: java inheritance interface casting implementation

我有界面Foo

public interface Foo {
    public void test();
}

Class FooChild实现了接口Foo。

public class FooChild implements Foo {

    @Override
    public void test() {...}

    public void test2() {...}
}

我必须在代码中的某个地方调用函数test2。

Foo f = new FooChild();
((FooChild) f).test2();

我真的很讨厌将类接口转换为类。

所以我添加了另一个界面栏。

public interface Bar extends Foo {
    public void test2();
}

public class FooChild implements Bar {

    @Override
    public void test() {...}

    @Override
    public void test2() {...}
}

现在我将test2()调用为接口而不是类。

Foo f = new FooChild();
((Bar) f).test2();

我可以将函数test2添加到接口Foo, 但实现Foo的类太多了。

如果我添加该函数,我必须向所有实现Foo的类添加代码。

虽然我可以这样做,但实际上我没有编辑Foo的权限。

有没有更好的方法来解决这个问题? (希望没有施法)

编辑: f作为方法参数传递。

正如乔恩所说,我应该更加具体。 对不起,感到困惑。

public void doSomething(Foo f) {
...
}

3 个答案:

答案 0 :(得分:6)

如果您知道变量值 的类型为FooChild,那么只需声明:

FooChild f = new FooChild();
f.test2();

如果有什么理由不适合你,那就是你没有告诉我们的事情......

编辑:好的,显然它确实是一个方法参数:

public void doSomething(Foo f) {
    ((FooChild) f).test2();
}

......所以不,你无能为力,以避免演员表演。演员表示超出声明的变量类型已经保证的值的要求 - 在这种情况下,你想说“它必须实际上是FooChild,而不仅仅是Foo的任何实现“。如果您无法更改参数,则转换是 表达的方式。

答案 1 :(得分:5)

Bar f = new FooChild();
f.test2();

答案 2 :(得分:1)

很难说出你在这里想要什么,但是你可以为任何Foo对象创建一个辅助函数来返回一个FooChild。

public FooChild getImpl(Foo input){
  if (input instanceof FooChild){
    return (FooChild)input;
  }else{
    return null;
  }
}

这样你可以像这样调用你的助手函数(假设不​​是null:

getImpl(f).test2();

注意:此代码根本不检查空值,您需要在代码中执行此操作。