简体   繁体   English

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

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

I have two classes, Dog and Cat: 我有两个班,狗和猫:

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

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

In my main, I take the name as String, either "Cat", or "Dog". 在我的主要内容中,我将名称命名为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();
}

But now I want to be able to call the method "speak". 但现在我希望能够将方法称为“说话”。 But then I have to cast the object to either cat or dog, since "Object" obviously does not have built in "speak" method. 但是我必须将对象强制转换为猫或狗,因为“对象”显然没有内置“说话”方法。 So my solution was to make another class (I can't use if-statements btw): 所以我的解决方案是创建另一个类(我不能使用if-statements btw):

class Animal{
    public void speak(){
    }
}

And then both "Cat" and "Dog" can extend Animal and override its methods. 然后“Cat”和“Dog”都可以扩展Animal并覆盖其方法。 Is there any other way to do this WITHOUT making another method / using if-statements? 有没有其他方法可以做到这一点没有使用另一个方法/使用if语句? (Including switch case, ternary operator). (包括开关盒,三元操作器)。 Thanks in advance. 提前致谢。

ANOTHER QUESTION: If I take in the name of the METHOD in as an input as well, how would I call it? 另一个问题:如果我将METHOD的名称作为输入,我该怎么称呼它? For example: 例如:

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

If I take in as a String either "speak" or "bark", how would I call the method without using if-statements? 如果我以“说”或“吠叫”的形式接受字符串,如何在不使用if语句的情况下调用该方法?

You can do it with reflection using Class.getMethod and Method.invoke . 您可以使用Class.getMethodMethod.invoke进行反射。

Creating an Animal class is really the cleanest way, though. 但是,创建Animal类确实是最干净的方法。 What stops you from doing that? 什么阻止你这样做?

You are on the right track. 你走在正确的轨道上。 The easiest way is to create an animal class and have dog and cat inherit from it and make them both implement their own version of speak(). 最简单的方法是创建一个动物类,让狗和猫从它继承并使它们都实现自己的speak()版本。 Is there a reason you don't want to create another class? 有没有理由你不想创建另一个类?

Alright, here are two methods ordered by preference: 好的,这里有两个按优先顺序排序的方法:

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();
    }
}

I'm using a baseclass since it can be assumed that an Animal will hold more fields that are shared by each animal (name, species, etc). 我正在使用基类,因为可以假设Animal将拥有更多由每只动物共享的字段(名称,物种等)。 If this isn't the case then you should go for an interface. 如果不是这种情况,那么你应该去一个界面。

Or with reflection: 或者用反思:

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();
        }
    }
}

You don't have to create class Animal - create an interface : 您不必创建class Animal - 创建一个interface

interface Animal{
    public void speak();
}

and have both Cat and Dog implement it. 并同时拥有CatDog实现它。 Then in main() : 然后在main()

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

No need to cast or use if/else. 无需强制转换或使用if / else。

The only reason to use inheritance/abstract classes is when you want to reuse functionality (implement a method once and use it in a few classes). 使用继承/抽象类的唯一原因是当您想要重用功能时(实现一次方法并在几个类中使用它)。 Otherwise - better use interfaces. 否则 - 更好地使用接口。

As for the method name, if you want the "wise-ass" solution: use switch (supported from Java 7). 至于方法名称,如果你想要“明智的”解决方案:使用switch (Java 7支持)。 Otherwise, see @immibis's answer. 否则,请参阅@ immibis的回答。

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

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