繁体   English   中英

Java:使用对象名称的String输入创建对象

[英]Java: Creating object with String input of the object's name

我有两个班,狗和猫:

class Dog{
   public void speak(){
        System.out.print("Woof!");
   }
}

class Cat{
   public void speak(){
       System.out.print("Meow!");
   }
}

在我的主要内容中,我将名称命名为String,“Cat”或“Dog”。

public static void main(String [] args){
    Scanner sc = new Scanner(System.in);
    String name = sc.next();

    Class<?> cls = Class.forName(name);
    Object object = cls.newInstance();
}

但现在我希望能够将方法称为“说话”。 但是我必须将对象强制转换为猫或狗,因为“对象”显然没有内置“说话”方法。 所以我的解决方案是创建另一个类(我不能使用if-statements btw):

class Animal{
    public void speak(){
    }
}

然后“Cat”和“Dog”都可以扩展Animal并覆盖其方法。 有没有其他方法可以做到这一点没有使用另一个方法/使用if语句? (包括开关盒,三元操作器)。 提前致谢。

另一个问题:如果我将METHOD的名称作为输入,我该怎么称呼它? 例如:

class Dog{
    public void speak(){}
    public void bark(){}
}

如果我以“说”或“吠叫”的形式接受字符串,如何在不使用if语句的情况下调用该方法?

您可以使用Class.getMethodMethod.invoke进行反射。

但是,创建Animal类确实是最干净的方法。 什么阻止你这样做?

你走在正确的轨道上。 最简单的方法是创建一个动物类,让狗和猫从它继承并使它们都实现自己的speak()版本。 有没有理由你不想创建另一个类?

好的,这里有两个按优先顺序排序的方法:

abstract class Animal {
    public abstract void speak();
}

class Dog extends Animal {
    @Override
    public void speak() {
        System.out.println("Woof woof");
    }
}

class Cat extends Animal {
    @Override
    public void speak() {
        System.out.println("Miauw");
    }
}

public static void main(String[] args) {
    String type = "Dog";
    Class<?> clazz;
    try {
        clazz = Class.forName(type);
        Animal pet = (Animal) clazz.newInstance();
        pet.speak();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

我正在使用基类,因为可以假设Animal将拥有更多由每只动物共享的字段(名称,物种等)。 如果不是这种情况,那么你应该去一个界面。

或者用反思:

public class Test {
    public static void main(String[] args) {
        String type = "Dog";
        Class<?> clazz;
        try {
            clazz = Class.forName(type);
            for(Method method : clazz.getMethods()){
                if(method.getName().equals("speak")){
                    method.invoke(clazz.newInstance(), null);
                }
            }
        } catch (CException e) {
            e.printStackTrace();
        }
    }
}

您不必创建class Animal - 创建一个interface

interface Animal{
    public void speak();
}

并同时拥有CatDog实现它。 然后在main()

Class<?> cls = Class.forName(name);
Animal animal = cls.newInstance();
animal.speak();

无需强制转换或使用if / else。

使用继承/抽象类的唯一原因是当您想要重用功能时(实现一次方法并在几个类中使用它)。 否则 - 更好地使用接口。

至于方法名称,如果你想要“明智的”解决方案:使用switch (Java 7支持)。 否则,请参阅@ immibis的回答。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM