【发布时间】:2012-07-07 15:58:53
【问题描述】:
我有以下设置:
class Base {};
class ImplA extends Base {};
class ImplB extends Base {};
class ImplC extends Base {};
Base baseFactory(int type) {
switch(type) {
case 0:
return new ImplA();
case 1:
return new ImplB();
case 2:
return new ImplC();
}
Base a = baseFactory(0);
Base b = baseFactory(1);
Base c = baseFactory(2);
List<Base> list = new ArrayList<Base>();
list.add(a);
list.add(b);
list.add(c);
// Somewhere else I have:
interface BaseHandler {
process(ImplA a);
process(ImplB b);
process(ImplC c);
};
现在,我想做的事情大致如下:
class Processor {
BaseHandler bh;
Processor(BaseHandler bh) {
this.bh = b;
}
void processList(List<Base> list) {
for (Base x : list) {
bh.process(x);
}
}
然后让用户实现 BaseHandler 并能够构造一个 Processor 来对 Base 列表中的每个元素进行操作。
但是,这不起作用,因为未定义 process(Base)。只添加 3 个 if 语句似乎很简单,但我已经有了一个类似 switch 的结构来构建扩展 Base 的类的实例。似乎没有必要一遍又一遍地重复这一点。有没有办法实现这个想法,而不需要编写一个中间步骤来确定列表中每个 Base 的运行时类并调用适当的方法(实际上是另一个 switch 案例——但它会是 if 的)?
我认为一种解决方法是让每个 Base 都有一个抽象的 process 方法,该方法需要由 Impl 类实现。但是,这在我的情况下是不可接受的,因为用户不会实现 Impl 类。基本上,我需要 process 作为用户定义的回调。此外,process 成为 Impl 或 Base 类的成员是没有意义的,因为它没有任何关系。这是一个单独的回调,需要动态响应调用它的类型。并且类型总是保证是 Base 的子类。
【问题讨论】:
-
不。你已经列出了所有的可能性。记住,重载决议总是在编译时完成。如果你想调用一个特定的重载,你必须在编译时知道这个对象有那个类。 (当然,显式测试和强制转换就足以向编译器证明对象的类型。)
标签: java polymorphism overloading factory-pattern