簡體   English   中英

java-從列表中調用子類

[英]java- calling sub-class from a list

我有以下代碼:

public abstract class animal {
public final static int elephent = 1;
public final static int dog = 2;

和兩個子類:

public class elephant extends animal {

    public final static int type = animal.elephent;

    public elephant (String name){
        super(name);
    }

}

public class dog extends animal {

    public final static int type = animal.dog;

    public dog (String name){
        super(name);
    }

}

現在,說我有一個帶有字母E-大象和D-狗的字符列表。 以及相同大小的動物類別的空列表。 對於第一個列表上的每個字符,我想創建一個正確的動物的新實例。 例如:[“ d”,“ e”,“ d”]會給我一個清單:[新狗,新象,新狗]希望我說清楚,在此先感謝您的幫助。

這種設計不是最佳的。 您使用整數變量指示類型,這確實不是一個好主意。

第一個改進:使類型指示成為枚舉。

public enum AnimalType {
    ELEPHANT, DOG
}

現在在您的動物類中添加一個類型字段:

public abstract class Animal {
    private final AnimalType type;
    private final String name;
    protected Animal(AnimalType type, String name) {
        this.type = Objects.requireNonNull(type);
        this.name = Objects.requireNonNull(name);
    }
    // more fields and methods here
}

大象看起來像那樣(狗也差不多):

public class Elephant extends Animal {
    public Elephant(String name) {
        super(AnimalType.ELEPHANT, name);
    }
    // more fields and methods here
}

主要缺點:每次添加一個新的動物類型的時候,你必須添加一個新的類,並添加一個類型為枚舉。 這不是最好的設計。 此外,因為子類型已經保存了類型信息,所以實際上不需要類型枚舉。

Elephant類的一個實例是大象(狗相同)。 它不需要類型字段。

第二個改進:完全刪除類型指示。 沒有整數,沒有枚舉。 只需有抽象類和子類。

現在是您的問題,如何從任何字符輸入中獲取正確的實例。 這稱為映射。 你想映射

Elephant類的字符“ E”。

Dog類的字符“ D”。

這可以通過Java Map實現:

Map<Character, Class<? extends Animal>> charToAnimal = new HashMap<>();
charToAnimal.put('E', Elephant.class);
charToAnimal.put('D', Dog.class);

Class<? extends Animal> animalClass = charToAnimal.get('E');
String name = ...;
Animal animal = animalClass.getConstructor(String.class).newInstance(name); // will be an Elephant instance

該映射應該在您需要該行為的任何類中維護​​,或者如果您只是在學習如何做,則可以在main方法中維護。

請注意,我使用了一種稱為反射的Java機制,只是為了創建實例,因為沒有其他通用方法可以處理實例化。

另一種方法是執行相同操作的方法:

public Animal createAnimal(char c, String name) {
    if (c == 'E') {
        return new Elephant(name);
    } else if (c == 'D') {
        return new Dog(name);
    } else {
        throw new IllegalArgumentException(c);
    }
}

無論哪種方式,您都不僅需要添加一個ne動物子類,而且還必須在地圖中添加一個條目(請參見上文)或該方法的if分支。


編輯,正如我在這種情況下再次想到的那樣。

您可以使用枚舉方法,並將類實例化放入此枚舉。 采取上面的動物類和以下類型的枚舉(未選中):

public enum AnimalType {
    ELEPHANT('E', Elephant.class),
    DOG('D', Dog.class);

    private static final Map<Character, Class<? extends Animal>> CHAR_TO_ANIMAL = new HashMap<>();
    AnimalType(char c, Class<? extends Animal> animalClass) {
        CHAR_TO_ANIMAL.put(c, animalClass)
    }
    public Animal createAnimal(char c, String name) {
        if (c == 'E') {
            return new Elephant(name);
        } else if (c == 'D') {
            return new Dog(name);
        } else {
            throw new IllegalArgumentException(c);
        }
    }
}

因此,您可能要考慮的事情之一是switch-case語句。 因此,在Java中,您可以執行以下操作:

// get a char from the list.
char animal;

switch(animal)
{
    case'e':
        Elephant varName = new Elephant("Dumbo");
        newList.add(varName);
        break;
}

我沒有在此處包括所有內容,但這應該可以幫助您入門。 您將需要通過數據結構查找迭代(循環)。

老實說,自從我編寫任何Java以來​​已經有一段時間了,但這是您可以執行此操作的一種方式。 還有其他方法也可以執行此操作,例如也可以使用if塊。

希望這可以幫助。

我認為你需要的是一個靜態工廠方法返回一個實例,這是一種方法。

抽象類:

public abstract class animal {
public final static char elephent = 'E';
public final static char dog = 'D';
}

大象班:

public class Elephant extends Animal {

    private char myType;
    private String name;

    public Elephant(char type, String name) {
        super();
        this.myType = type;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public char getMyType() {
        return myType;
    }

    public void setMyType(char myType) {
        this.myType = myType;
    }

}

狗類:

public class Dog extends Animal {

    private char myType;
    private String name;

    public Dog(char type, String name) {
        super();
        this.myType = type;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public char getMyType() {
        return myType;
    }

    public void setMyType(char myType) {
        this.myType = myType;
    }

}

工廠類別:

public class FactoryMethod {

    static char getAnimalIndex(char type){

        switch (type) {
        case 'E':
        case 'e':
            return Animal.ELEPHANT;
        case 'D':
        case 'd':
            return Animal.DOG;
        default:
            throw new IllegalArgumentException(String.valueOf(type));
        }
    }

    public static Animal getInstance(char type, String name){
        Animal myCategory = null;
        switch (getAnimalIndex(type)) {
        case Animal.ELEPHANT:
            myCategory = new Elephant(type,name);
            break;
        case Animal.DOG:
            myCategory = new Dog(type,name);
            break;
        }
        return myCategory;
    }

}

用法:

如果您需要使用動物類索引,或者將其與列表中的字符一起使用,則此工廠方法有效。 獲取實例:

//using Animal index
FactoryMethod.getInstance(Animal.ELEPHANT,"Elephant");
FactoryMethod.getInstance(Animal.DOG,"Dog");

//using characters in list
FactoryMethod.getInstance('character_in_list_here',"Name OF The Animal Here");

由於它是靜態方法,因此您無需使用FactoryMethod實例即可使用。 我希望這就是你所需要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM