简单的面向对象编程概念

时间:2012-03-11 01:54:59

标签: java oop

它可能看起来像是一个虚假的问题,但我很难解决这个问题:

我们有一个抽象的class AnimalCat以及Dog来扩展它。在Animal中,我们有一个抽象的方法produceSound();。正如你可能猜到Cat它应该返回“毛”和Dog - “宝”或类似的东西。这没关系,但现在我们必须在static中编写Animal class方法,根据声音的不同,返回CatDog个对象。例如: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");

6 个答案:

答案 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的消费应用需要是什么?您的应用程序需要对它所使用的类做什么?除非这些假设是明确的,否则不能假设。