java - 如何确保使用子类参数调用的方法与通用类对象一起使用?

标签 java generic-programming

例如,我有 3 门课:

父类(super class):动物

子类扩展父类(super class):CatTiger

我编写了一个检查器类AnimalChecker来区分动物的类型,并使每种类型调用不同的方法(不同类型的参数,相同的方法名称)。 如果使用 C++ 模板,则可以完成此类工作,想知道他们是使其与 Java 一起工作的简单方法,我做了一些尝试,但还没有得到它。 :

AnimalChecker defined below:

public abstract class AnimalChecker {
    private List<Class<? extends Animal>> mAnimals;
    public AnimalChecker(Class<? extends Animal>... animals) {
        mAnimals = Arrays.asList(animals);
    }
    public boolean CheckAnimal(Animal animal) {
        Iterator<Class<? extends Animal>> it = mAnimals.iterator();
        while (it.hasNext()) {
            Class clazz = it.next();
            if (clazz.isInstance(animal)) {
                onCheck(animal, clazz);
                return true;
            }
        }
        return false;
    }
    public abstract void onCheck(Animal animal, Class<? extends Animal> clazz);
}

Then I tried implement the class, do the specific work for each type:

public class Main {
    public static MyChecker msChecker = new MyChecker();
    public static void main(String[] args) {
        AnimalChecker checker = new AnimalChecker(Cat.class, Tiger.class) {
            @Override
            public void onCheck(Animal animal, Class<? extends Animal> clazz) {
                System.out.println(clazz.toGenericString());
                msChecker.onCheck(clazz.cast(animal));
            }
        };
        checker.CheckAnimal(new Tiger());
        checker.CheckAnimal(new Cat());

        MyChecker myChecker = new MyChecker();
        myChecker.onCheck(new Tiger());
        myChecker.onCheck(new Cat());
    }

    static class MyChecker {
        public void onCheck(Animal animal) {
            System.out.println("Animal");
        }
        public void onCheck(Cat animal) {
            System.out.println("Cat");
        }
        public void onCheck(Tiger animal) {
            System.out.println("Tiger");
        }
    }
}

The output below isn't what I want:

public class test.Tiger
Animal
public class test.Cat
Animal
Tiger
Cat

I wanna to make the result

public class test.Tiger
Tiger
public class test.Cat
Cat
Tiger
Cat

最佳答案

Java 不会为你做这件事,很简单。您试图让 Java 执行的操作称为 multiple dispatch ,而Java不支持。方法参数的类型仅在编译时由编译器与参数值进行匹配,而不是在运行时匹配。在您的代码中,编译器了解的有关参数值的最具体信息是它的类型为 Animal ,因此它选择链接到该方法。 clazz.cast() 调用没有帮助,因为相同的参数适用于 clazz 变量:编译器知道的最具体的事情是它是 ?扩展了 Animal,因此就编译器而言,cast() 调用的结果是 Animal 类型。

当然,您可以通过多种方法在 Java 中实现类似的效果,但我认为我无法为您选择一种。上面链接的维基百科文章中有一个关于多重调度的示例,您可能还需要考虑类似于 visitor pattern 的内容。 ,但不要觉得受到模式的束缚。 :)

关于java - 如何确保使用子类参数调用的方法与通用类对象一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28803068/

相关文章:

c++ - 如何清除通用 C++ 代码中的 `double`?

rust - 在 Rust 中实现通用的可递增特征

java - 使 MySQL 以英语(而不是波斯语)存储所有数字

java - 在运行时创建和覆盖 Java 枚举对象 [GregTech/minecraft]

java - 通过 Cursor.getSystemCustomCursor 可以使用哪些游标?

java - Sublime Text 2 Play IDE 1.2.5

c++ - 是否可以概括一个将 STL 容器作为参数的函数?

c++ - 用作模板函数输入的函数的 void 返回值被视为参数

vb.net - 如何使 VB.NET 函数的参数作为泛型类型?

java - 验收测试增量值