免责声明:我知道有很多关于多态性的问题,但我找不到适合我的问题的答案。如果你的谷歌比我的好,请原谅这个骗子。
我有一个使用继承的模型,例如下面的例子。
public abstract class Base {
// ...
}
public class ConcreteA extends Base {
private String someString;
// ...
}
public class ConcreteB extends Base {
private boolean someBool;
// ...
}
我还有一个List<Base>
,它由ConcreteA
或ConcreteB
s的对象组成。
我需要为列表中的每个对象生成一个图形视图,但ConcreteA
和ConcreteB
的结果元素不同。从上面的示例中,ConcreteA
的视图将是文本字段,而ConcreteB
的视图将是一个复选框。
如何使用OO原则实现这一目标?
答案 0 :(得分:2)
不是模式 - 这就是抽象的全部。声明一个方法,希望Base
的所有子类都能实现,并且每个子类都必须以自己的方式实现它。
显然你会传递参数和/或得到方法的结果。
public abstract class Base {
abstract void graphicalView();
}
public class ConcreteA extends Base {
@Override
void graphicalView() {
}
}
public class ConcreteB extends Base {
@Override
void graphicalView() {
}
}
public void test() throws IOException {
List<Base> bases = new ArrayList<>();
for ( Base b : bases ) {
b.graphicalView();
}
}
答案 1 :(得分:2)
我认为您正在寻找 Visitor Design Pattern 。
来自维基百科:
在面向对象的编程和软件工程中,访问者 设计模式是一种将算法与对象分离的方法 它运作的结构。这种分离的实际结果 是能够向现存的对象结构添加新操作 没有修改结构。这是一种跟随的方式 开放/封闭原则。
实质上,访问者允许向a添加新的虚拟功能 类的系列,无需修改类。相反,一个访客 创建了一个实现所有适当的类 虚函数的特化。访客拿走了 实例引用作为输入,并通过double实现目标 调度。
答案 2 :(得分:2)
您遇到的问题是,当调用者必须知道具体类型时,您在某处返回List<Base>
。
通常这是因为有人试图使方法更通用。例如。如果有人有这种服务方法
public List<ConcreteA> doSomethingA(){ ... }
public List<ConcreteB> doSomethingB(){ ... }
他可能认为引入一个超类Base
是一个更好的主意,这样两种方法都可以用
public List<Base> doSomething(){ ... }
如果调用者仅在Base
对象中进行了调换,那么这是一个好主意。这意味着ConcreateA
和ConcreteB
具有调用者仅依赖的一些常见行为。
但是在你的情况下,似乎调用者需要不再可用的具体类型信息,因为更通用的方法。
因此,您必须保留或重建类型信息。
使用自定义返回类型保留类型,而不是使方法通用
public class Result {
private List<ConcreteA> concreteA;
private List<ConcreteB> concreteA;
}
public Result doSomething();
使用instanceof
答案 3 :(得分:-1)
在这种情况下,我通常使用类似这样的泛型
public abstract class Base <T extends Shape>{
public abstract T drawShape();
}
public class ConcreatA extends Base<Circle> {
@Override
public Circle drawShape() {
return null;
}
}
public class ConcreatB extends Base<Square> {
@Override
public Square drawShape() {
return null;
}
}
所以现在你可以使用Shapes列表