根据用户输入选择子类?
问题描述:
我想根据用户输入选择特定的子类,但我不太确定如何执行此操作。例如:根据用户输入选择子类?
System.out.println("Select animal:\n1. Cat\n2. Dog");
int input = keyboard.nextInt();
if(input == 1){
Cat newPet = new Cat();
}
else{
Dog newPet = new Dog();
}
这只是我刚刚创建的一个快速示例,所以请原谅任何语法错误。我明白,一旦if语句结束,newPet
对象超出范围,因此不能再使用。我也尝试了一些案例,但这是行不通的,因为我宣称newPet
两次,尽管在程序的每次运行中只能访问一个。
根据用户输入的不同,程序中更多的不同因素会受到影响。我总是可以在每个不同的因素中使用if语句,但是想知道是否有更干净的方法来做到这一点?
答
您可以创建一个界面动物。 猫和狗应该实现动物。 您的代码可以改成像
System.out.println("Select animal:\n1. Cat\n2. Dog");
int input = keyboard.nextInt();
Animal pet=null;
if(input == 1){
pet = new Cat();
}
else{
pet = new Dog();
}
这将有助于保持更简洁的方法为好。
答
您可以用所需的子类填充地图和使用newInstance()方法:
界面动物 {
}
类Cat实现动物 {
}
级狗实施动物 {
}
Map<Integer, Class> animals= new HashMap<Integer, Class>();
animals.put(0, Cat.class);
animals.put(1, Dog.class);
System.out.println("Select animal:\n1. Cat\n2. Dog");
int input = keyboard.nextInt();
Animal yourAnimal = (Animal) animals.get(input).newInstance();
答
需要
-
工厂其中创建宠物实例(在Java中8:
Supplier<Pet>
) - 一个输入值之间的映射和工厂
- a 策略 what t如果没有提供有效的输入,则返回(如果没有工厂映射为输入值,或者返回默认宠物的默认工厂或空值,则可能是引发异常的检查)。
代码:
Map<Integer, Supplier<Pet>> factories = new HashMap<>();
factories.put(1, Cat::new);
factories.put(2, Dog::new);
Supplier<Pet> defaultPetSupplier =() -> null;
Function<Integer, Pet> f = i -> factories.getOrDefault(i, defaultPetSupplier).get();
System.out.println("Select animal:\n1. Cat\n2. Dog");
int input = keyboard.nextInt();
Pet pet = f.apply(input);
答
如果你想避免类型转换,那么你必须做一点点更多的工作。但是你仍然必须使用多态概念。 创建一个名为Pet的接口,并将Pet接口中Cat和Dog类所包含的所有方法作为抽象方法。
class Cat {
public void catMethod1() {
}
public void catMethod2() {
}
}
class Dog {
public void dogMethod() {
}
}
interface Pet {
public void catMethod1();
public void catMethod2();
public void dogMethod();
}
class HelperClass implements Pet {
Cat cat;
Dog dog;
public HelperClass(int input) {
if (input == 1) {
cat = new Cat();
} else {
dog = new Dog();
}
}
@Override
public void dogMethod() {
if (dog == null) {
return;
}
dog.dogMethod();
}
@Override
public void catMethod1() {
if (cat == null) {
return;
}
cat.catMethod1();
}
@Override
public void catMethod2() {
if (cat == null) {
return;
}
cat.catMethod2();
}
}
现在你可以访问没有类型转换的方法。
Pet newpet = new HelperClass(input);
newpet.catMethod2();
+0
用这种方法,你不必修改你的Dog和Cat类。 –
另请注意,如果'Cat'和'Dog'不共享一个通用的超类/接口,则可以将'pet'声明为Object,但创建一个通用接口更清晰。 –
@Gaël:在这种情况下,它会调用我们需要的任何方法来形式化它,但这种方法可能有效,但它不会更清洁。 –
我宁愿在这个场景中使用一个抽象类'Animal',而不是一个接口。 :)但是我知道你的意思,因为它可能是多态性最常见的例子。 – LordAnomander