簡體   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