Java多态:找到正确的设计模式

时间:2017-07-05 15:23:57

标签: java oop design-patterns polymorphism

免责声明:我知道有很多关于多态性的问题,但我找不到适合我的问题的答案。如果你的谷歌比我的好,请原谅这个骗子。

我有一个使用继承的模型,例如下面的例子。

public abstract class Base {
// ...
}

public class ConcreteA extends Base {
    private String someString;
// ...
}

public class ConcreteB extends Base {
    private boolean someBool;
// ...
}

我还有一个List<Base>,它由ConcreteAConcreteB s的对象组成。

我需要为列表中的每个对象生成一个图形视图,但ConcreteAConcreteB的结果元素不同。从上面的示例中,ConcreteA的视图将是文本字段,而ConcreteB的视图将是一个复选框。

如何使用OO原则实现这一目标?

4 个答案:

答案 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对象中进行了调换,那么这是一个好主意。这意味着ConcreateAConcreteB具有调用者仅依赖的一些常见行为。

但是在你的情况下,似乎调用者需要不再可用的具体类型信息,因为更通用的方法。

因此,您必须保留或重建类型信息。

  1. 使用自定义返回类型保留类型,而不是使方法通用

     public class Result {
         private List<ConcreteA> concreteA;
         private List<ConcreteB> concreteA;
     }
    
     public Result doSomething();
    
  2. 使用instanceof

  3. 重新构建类型信息
  4. 通过隐藏访问者模式重建类型信息。

答案 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列表

相关问题