如何创建不同类型对象的集合以将其与多态性一起使用

时间:2016-05-28 17:04:36

标签: java list overloading

我对集合中不同类型的对象有问题,在这种情况下是ArrayList,这里有一个例子:

public interface CustomObject {}
public class CustomObjectA implements CustomObjects {}
public class CustomObjectB implements CustomObjects {}

在主要部分我称之为myMethod:

ArrayList<CustomObject> list = new ArrayList<>();

for(int i=0; i < list.size(); i++) {
   myMethod(list.get(i));
}

myMethod定义为重载,如下所示:

public void myMethod(CustomObjectA a) { ... }
public void myMethod(CustomObjectB b) { ... }

存在编译错误。我怎么解决?什么是正确的方法(收藏,泛型,通配符?)

3 个答案:

答案 0 :(得分:1)

解决此问题的一种方法是使用访问者模式,它允许您附加功能,而无需触及域对象

// A visitor, which can 'visit' all your types
interface CustomObjectVisitor {
    void visitA(CustomObjectA a);
    void visitB(CustomObjectB b);
}

// Make CustomObject a visitee
public interface CustomObject {
    void accept(CustomObjectVisitor visitor);
}

// Implement the classes with the accept method
public class CustomObjectA implements CustomObject {
    @Override public void accept(CustomObjectVisitor visitor) {
        visitor.visitA(this);
    }
}
public class CustomObjectB implements CustomObject {
    @Override public void accept(CustomObjectVisitor visitor) {
        visitor.visitB(this);
    }
}

现在,您可以将Main课程设为这样的访问者:

public class Main implements CustomObjectVisitor {
    public void methodThatDidntWorkBefore() {
        ArrayList<CustomObject> list = new ArrayList<>();
        for(CustomObject obj: list) {
            obj.accept(this);
        }
    }

    @Override public void visitA(CustomObjectA a) { ... }
    @Override public void visitB(CustomObjectB b) { ... }
}

查看WikiPedia,一旦你绕过它,它真的很有用。

答案 1 :(得分:0)

使用:

public interface CustomObject { void myMethod(); }
public class CustomObjectA implements CustomObjects {
    @Override
    public void myMethod() {...}
}
public class CustomObjectB implements CustomObjects {
    @Override
    public void myMethod() {...}
}

然后:

ArrayList<CustomObject> list = new ArrayList<>();

for(int i=0; i < list.size(); i++) {
   list.get(i).myMethod(); // invoke dynamic
}

将执行与对象的动态类型相对应的方法。

e.g。如果get(i)返回动态类型为CustomObjectA的对象,则会执行CustomObjectA::myMethod

答案 2 :(得分:0)

您可以尝试这样的事情:

public class myMethodClass {

    public static void main(String[] args) {
        ArrayList<CustomObject> list = new ArrayList<>();

        for(int i=0; i < list.size(); i++) {
           myMethod(list.get(i));
        }
    }

    public static void myMethod(CustomObject o){
        if(o instanceof CustomObjectA) myMethod((CustomObjectA) o);
        if(o instanceof CustomObjectB) myMethod((CustomObjectB) o);
    }
    public static void myMethod(CustomObjectA a) { }
    public static void myMethod(CustomObjectB b) { }
}

interface CustomObject {}
class CustomObjectA implements CustomObject {}
class CustomObjectB implements CustomObject {}