它可能看起来像是一个虚假的问题,但我很难解决这个问题:
我们有一个抽象的class Animal
和Cat
以及Dog
来扩展它。在Animal
中,我们有一个抽象的方法produceSound();
。正如你可能猜到Cat
它应该返回“毛”和Dog
- “宝”或类似的东西。这没关系,但现在我们必须在static
中编写Animal class
方法,根据声音的不同,返回Cat
或Dog
个对象。例如:identifyAnimal("Mao")
应返回Cat
。
问题:如何实施identifyAnimal(String sound)
方法?
以下是层次结构的一些简单示例:
动物类
public abstract class Animal {
protected abstract String produceSound();
protected static void identifyAnimal(String animalSound) {
// TODO
}
}
Cat class
public class Cat extends Animal{
@Override
protected String produceSound() {
return "Mao";
}
}
狗类
public class Dog extends Animal{
@Override
protected String produceSound() {
return "Bao";
}
}
测试类
public class AnimalTest {
public static void main(String[] args) {
Animal.identifyAnimal("Bao");
}
}
在调用AnimalTest
的{{1}}课程中,我们应该获得Animal.identifyAnimal("Bao");
。
答案 0 :(得分:3)
private static Class[] animalTypes = [Dog.class, Cat.class];
public static String identifyAnimal(String animalSound)
{
for (int i = 0; i < animalTypes.length; i++) {
Animal a = animalTypes[i].newInstance();
String s = a.produceSound();
if (animalSound.equals(s))
return animalTypes[i].getName();
}
return null;
}
答案 1 :(得分:2)
所以这是一种(可怕的)方法。我实际上抽搐了一下。 我不知道你正在使用什么语言,所以我会使用c ++(抱歉当前模式),但如果我们在C#中,你可以用Dictionarys替换地图,无论如何。这是一个糟糕的方式,但应该工作(概念上,无论如何)
...再次可怕...
公共抽象类Animal {
protected abstract String produceSound();
protected static map<string, string> SoundList;
protected static bool registerSound(string sound, string type)
{
return (SoundList.insert( pair<string, string>(sound, type)))->second;//true if worked false if already there
}
protected static string identifyAnimal(string animalSound)
{
map<string,string>::iterator result = SoundList.find(sound);
if(result != SoundList.end())
return result->second;
else
return "What The Hell Is This!?";
}
}
Cat class
public class Cat extends Animal
{
Cat()
{
Animal::registerSound("Mao","Cat");
}
@Override
protected String produceSound() {
return "Mao";
}
}
答案 2 :(得分:1)
abstract class Animal {
static Map<String,String> map = new HashMap<String,String>();
public Animal(String value) { map.put(produceSound(), value); }
protected abstract String produceSound();
protected static void identifyAnimal(String animalSound) {
System.out.println(map.get(animalSound));
}
}
class Cat extends Animal {
@Override
protected String produceSound() { return "Mao"; }
Cat(){ super("CAT"); }
}
class Dog extends Animal {
@Override
protected String produceSound() { return "Bao"; }
Dog(){ super("DOG"); }
}
class Test {
public static void main(String[] args) {
new Dog();
new Cat();
Animal.identifyAnimal("Bao");
}
}
答案 3 :(得分:0)
使用您拥有的预定义声音进行切换,并让每个声音返回一个带有动物名称的字符串。例如,“Mao”返回字符串“Cat”,依此类推。 还有一件事让你识别动物方法returna string而不是void。
答案 4 :(得分:0)
您可以使用反射来获取扩展Animal的所有类型的列表,使用Activator循环遍历它们以创建每个类型的实例,在每个类型上运行produceSound,直到找到与animalSound匹配的返回值,并返回该实例。如果你想避免你的Animal类知道扩展它的内容,那么效果很慢但很有效。
答案 5 :(得分:0)
您要解决的问题的性质是什么?没有“正确”的方式独立于问题。
班级Animal
的消费应用需要是什么?您的应用程序需要对它所使用的类做什么?除非这些假设是明确的,否则不能假设。