简体   繁体   English

java-从列表中调用子类

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

I have this code: 我有以下代码:

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

and two sub-classes: 和两个子类:

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

}

now, say I have a list of Chars with the letters E- elephant and D- dog. 现在,说我有一个带有字母E-大象和D-狗的字符列表。 and an empty list of animals class of the same size. 以及相同大小的动物类别的空列表。 and for every char on the first list I want to create a new instance of the right animal. 对于第一个列表上的每个字符,我想创建一个正确的动物的新实例。 example: ["d","e","d"] would give me a list of: [new dog, new elephant, new dog] hope I made myself clear, thanks in advance for the help. 例如:[“ d”,“ e”,“ d”]会给我一个清单:[新狗,新象,新狗]希望我说清楚,在此先感谢您的帮助。

This design is not optimal. 这种设计不是最佳的。 You are indicating the type with an integer variable, which really is not a good idea. 您使用整数变量指示类型,这确实不是一个好主意。

First improvement: Make the type indication an enum. 第一个改进:使类型指示成为枚举。

public enum AnimalType {
    ELEPHANT, DOG
}

Now add a type field in your animal class: 现在在您的动物类中添加一个类型字段:

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
}

An elephant then looks like that (dog is similar): 大象看起来像那样(狗也差不多):

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

The main disadvantage: Each time you add a new animal type, you must add a new class and add a type to the enumeration. 主要缺点:每次添加一个新的动物类型的时候,你必须添加一个新的类,并添加一个类型为枚举。 This is not the best design. 这不是最好的设计。 Additionally, the type enum is not really needed, as the sub types already hold the type information 此外,因为子类型已经保存了类型信息,所以实际上不需要类型枚举。

An instance of class Elephant is an elephant (dog the same). Elephant类的一个实例是大象(狗相同)。 It does not need the type field. 它不需要类型字段。

Second improvement: Delete the type indication completely. 第二个改进:完全删除类型指示。 No integers, no enums. 没有整数,没有枚举。 Just have the abstract class and the sub classes. 只需有抽象类和子类。

Now your question, how to get the correct instance from any character input. 现在是您的问题,如何从任何字符输入中获取正确的实例。 This is called a mapping. 这称为映射。 You want to map 你想映射

the character 'E' to the class Elephant . Elephant类的字符“ E”。

the character 'D' to the class Dog . Dog类的字符“ D”。

This can be achieved by a Java Map : 这可以通过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

This map should be maintained in any class you need that behavior, or maybe in the main method if you are just learning how to do that. 该映射应该在您需要该行为的任何类中维护​​,或者如果您只是在学习如何做,则可以在main方法中维护。

Note, that I used a Java mechanism called reflection, just to create an instance, as there is no other generic way to handle the instantiation. 请注意,我使用了一种称为反射的Java机制,只是为了创建实例,因为没有其他通用方法可以处理实例化。

Another approach would be a method that does the same: 另一种方法是执行相同操作的方法:

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

Either way, you have to add not only a ne animal sub class, but you have to add an entry into the map (see above) or an if branch to the method. 无论哪种方式,您都不仅需要添加一个ne动物子类,而且还必须在地图中添加一个条目(请参见上文)或该方法的if分支。


EDIT, as I thought again over this scenario. 编辑,正如我在这种情况下再次想到的那样。

You could go with the enum approach and put the class instantiation into this enum. 您可以使用枚举方法,并将类实例化放入此枚举。 Take the animal classes as above and the following type enum (not checked): 采取上面的动物类和以下类型的枚举(未选中):

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

So one of the things you may want to consider is a switch-case statement. 因此,您可能要考虑的事情之一是switch-case语句。 So in Java, you could do something like this: 因此,在Java中,您可以执行以下操作:

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

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

I've not included everything here, but this should get you started. 我没有在此处包括所有内容,但这应该可以帮助您入门。 You will need to look up iterating (looping) through a data structure. 您将需要通过数据结构查找迭代(循环)。

I will be honest, it's been a while since I've written any Java, but this is one way you could do this. 老实说,自从我编写任何Java以来​​已经有一段时间了,但这是您可以执行此操作的一种方式。 There are other ways to do this as well, such as using an if block as well. 还有其他方法也可以执行此操作,例如也可以使用if块。

Hope this helps. 希望这可以帮助。

I think what u need is an static factory method returns an instance.Here is one way of doing it. 我认为你需要的是一个静态工厂方法返回一个实例,这是一种方法。

Abstract Class: 抽象类:

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

Elephant Class: 大象班:

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

}

Dog Class: 狗类:

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

}

Factory Class: 工厂类别:

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

}

Usage: 用法:

if u need to use Animal class index or as u with the character from the list this factory method works. 如果您需要使用动物类索引,或者将其与列表中的字符一起使用,则此工厂方法有效。 To get instance: 获取实例:

//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");

Since it is a static method u can use without using FactoryMethod instance. 由于它是静态方法,因此您无需使用FactoryMethod实例即可使用。 I hope this is what u needed. 我希望这就是你所需要的。

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

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