基于运行时对象类型

时间:2017-05-31 13:12:27

标签: java inheritance design-patterns

我遇到这种情况:

我有一个抽象的课程,让我们说A,实施了好几次。 在应用程序的另一部分中,我有一个A对象列表,根据列表中对象的实际类型,我需要做几个操作。 作为一个例子

/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;

abstract class A{
    abstract void op();
}

class B extends A{
    void op(){
        System.out.println("b");
    }
    void opB(){
        System.out.println("it's b again!");
    }
}

class C extends A{
    void op(){
        System.out.println("c");
    }
    void opC(){
        System.out.println("it's b again!");
    }
}

class Ideone
{
    public static void doStuff(B b){
        b.opB();
        //Some operation unique to class B
    }

    public static void doStuff(C c){
        //some operation unique to class C
        c.opC();
    }

    public static void main (String[] args) throws java.lang.Exception
    {
        List<A> l = someMethodThatGivesMeTheList();
        for(A a: l){
            //Here it should use the right
            doStuff(a);
        }
    }
}

示例不编译,但解释了我想要做的事情。怎么样?

我发现只能应用访问者模式,但这需要修改A类及其子类来接受访问者,我宁愿避免使用它。

使用getClass()并切换\ if是笨拙的,不是我真正想要的。

在示例中我使用了两个静态方法,但是一些新类,包装器,只要它解决了问题就可以使用所有内容,我可以完全控制代码。

这里的类似问题是Calling method based on run-time type insead of compile-time type,但就我而言,我使用的是Java,因此不存在dynamic类型来解决我的问题。

编辑:我在这里写下我在评论中所写的内容,以便更清楚。该操作不能成为A的方法,因为它表示必须分离的事物,例如基于实际数据类型的GUI创建。并行层次结构可以作为包装器,但是仍然需要根据实际对象创建正确的GUI对象,这让我回到了同样的问题,或者至少在我看来。

EDIT 2(返回):我已经改变了一些示例,以更好地表明我需要根据实际的类来做事情。这在某种程度上远离我的情况,但问题是相同的,一个集合擦除了真正的对象类,我需要一种方法来更智能地恢复instanceofgetClass()

1 个答案:

答案 0 :(得分:1)

您是否检查了命令设计模式

  interface A{
    void op();
}

    class C implements A {
    public void op() {
        System.out.println("class c command method");
    }
}

class B implements A {
    public void op() {
        System.out.println("class B command method op");
    }
}

class D implements A {
    public void op() {
        System.out.println("class D method op");
    }
}

public class CommandDemo {
    public static List produceRequests() {
        List<A> list = new ArrayList<>();
        queue.add(new B());
        queue.add(new C());
        queue.add(new D());
        return list;
    }



    public static void main( String[] args ) {
        List list= produceRequests();
        for (Object command : list) {
            ((A)command).execute();
        }
    }
}

输出

class B command method op
class C command method 
class D method op