以通用方式处理不同类型的对象

时间:2013-12-16 11:40:51

标签: java inheritance polymorphism

我有一个函数,首先检查传递的参数的类型:

public void myFunc(Object myObj){
    if(myObj instanceof Student){
        Student p = (Student) myObj;
    }else{
        Teacher p = (Teacher) myObj;
    }

   //after above check I want to handle p in a generic way
   //of course the following p is not resolved...
   p.getName();
   p.registerSelf();
} 

p总是需要先施放。如何使编译器首先知道p的类型,然后调用Teacher&的公共函数。 Student有。{/ p>

使用apache avro自动生成我的人员和教师。我无法定义两个类(Person& Student)来扩展同一个类。

6 个答案:

答案 0 :(得分:1)

让学生和教师从共同的父母那里延伸 - 比如说人。 将方法getName和registerSelf放在Person中。那么然后无条件地对Person进行类型化,并调用你放在Person中的常用方法。

好的,“我的人员和教师是使用apache avro自动生成的。我无法定义两个类(Person& Student)来扩展同一个类。”

我认为这部分不是原来的问题。

基于这些新信息我会说:

1)我的一个项目中生成的类有类似的问题。我不认为有一个非常好的解决方案,除非你以某种方式迫使学生和教师在你生成这些类之后实现一些通用接口(并且不需要手动更改生成的类/我想你会想要这个要求,因为你可能会保留他们在一些版本控制系统/)。我建议你发一个新问题,因为一个重要的声明不是其初始版本的一部分。

2)另外你可能想看看http://en.wikipedia.org/wiki/Decorator_pattern不确定它是否适用于你的情况,但你检查出来,也许是。

3)你可以使用反射作为grexter89指出。这对你的情况来说可能是最好的。

答案 1 :(得分:0)

首先,您的代码无法编译。

其次:

public interface Person{
    String getName();
    void registerSelf();
}

public class Student implements Person{
     ....
}

public class Teacher implements Person{
     ....
}

并且您的代码更改为

public void myFunc(Object myObj){
    Person p = null;
    if(myObj instanceof Student){
        p = (Student) myObj;
    }else{
        p = (Teacher) myObj;
    }

   //after above check I want to handle p in a generic way
   //of course the following p is not resolved...
   p.getName();
   p.registerSelf();
} 

答案 2 :(得分:0)

如果Teacher& Student有类似的方法要调用,使用这些方法创建接口(或超类),然后使用myFunc(ParentClass myObj)并且不需要转换任何东西:

public void myFunc(ParentClass myObj){
    myObj.getName();
    myObj.registerSelf();
}

答案 3 :(得分:0)

Student pTeacher p具有范围,直到if子句。所以首先声明Person p = null

如果你想和每个人做同样的事情,那么为什么要使用instanceof。只需将方法提取到超类,然后在子类中覆盖它们。 Beware of instanceof

答案 4 :(得分:0)

如果您真的无法实施Interface,请查看Reflection

Here's an example on how to use it

答案 5 :(得分:0)

假设你不能让接口扩展类,你必须使用某种反射。可能的解决方案如下:

public void myFunc(Object myObj) {
    if (myObj instanceof Student) {
        Student p = (Student) myObj;
    } else {
        Teacher p = (Teacher) myObj;
    }

    //after above check I want to handle p in a generic way
    //of course the following p is not resolved...

    // define possible classes for invoking methods
    List<Class<?>> possibleClasses = new ArrayList<Class<?>>() {{
        add(Student.class);
        add(Teacher.class);
        add(NewUnknown.class);  // just in case for more possibilities
    }};

    if (possibleClasses.contains(myObj.getClass())) {
        try {
            // directly invoking these methods, assuming,
            // they exist in the defined classes
            myObj.getClass().getMethod("getName").invoke(myObj);
            myObj.getClass().getMethod("registerSelf").invoke(myObj);
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
            // handle exception, if method is not available in current class
        }
    }
}