Java 简单的面向对象编程概念

Java 简单的面向对象编程概念,java,oop,Java,Oop,对你来说,这可能是一个愚蠢的问题,但我很难解决这个问题: 我们有一个抽象的类动物和猫和狗来扩展它。在Animal中,我们有一个方法produceSound()这是抽象的。正如您可能猜到的那样,Cat应该返回“Mao”,而Dog应该返回“Bao”或类似的内容。这是可以的,但是现在我们必须在动物类中编写一个静态方法,根据对象的声音返回猫或狗对象。例如:identificationanimal(“Mao”)应返回Cat 问题:如何实现识别动物(字符串声音)方法 下面是层次结构的一些简单示例: 动物类

对你来说,这可能是一个愚蠢的问题,但我很难解决这个问题:

我们有一个抽象的
类动物
来扩展它。在
Animal
中,我们有一个方法
produceSound()这是抽象的。正如您可能猜到的那样,
Cat
应该返回“Mao”,而
Dog
应该返回“Bao”或类似的内容。这是可以的,但是现在我们必须在
动物类
中编写一个
静态
方法,根据对象的声音返回
对象。例如:
identificationanimal(“Mao”)
应返回
Cat

问题:如何实现
识别动物(字符串声音)
方法

下面是层次结构的一些简单示例:

动物类

public abstract class Animal {

    protected abstract String produceSound();

    protected static void identifyAnimal(String animalSound) {
        // TODO 
    }
}
猫类

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");
    }
}  
狗类

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");
    }
}  
测试类

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

调用
Animal.identificationanimal(“Bao”)时,在
AnimalTest
类中我们应该得到一只

用预定义的声音进行切换,让每个声音返回一个带有动物名称的字符串。例如,“Mao”返回字符串“Cat”等等。
还有一件事,让我们的IdentificationAnimal方法返回一个字符串,而不是void。

您可以使用反射来获取扩展Animal的所有类型的列表,使用Activator在它们之间循环,创建每个类型的实例,在每个类型上运行produceSound,直到找到与animalSound匹配的返回值,并返回该实例。如果你想避免你的动物类意识到是什么扩展了它,那么速度很慢,但很有效。

private static class[]animalTypes=[Dog.class,Cat.class];
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;
}
公共静态字符串IdentificationAnimal(字符串animalSound) { for(int i=0;i
您试图解决的问题的性质是什么?没有独立于问题的“正确”方式

消费应用程序需要类
动物
中的哪些内容?您的应用程序需要如何处理它所使用的类?除非这些假设是明确的,否则什么都不能假设。

所以这里有一个(可怕的)方法来做到这一点。实际上我有点抽搐。 我不知道您使用的是什么语言,所以我选择c++(抱歉,当前模式),不过如果我们使用c#,您可以用字典替换地图,不管怎样。这是一种糟糕的做事方式,但应该有效(无论如何,从概念上讲)

再次…可怕

public abstract class 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";
        }
    }
公共抽象类动物{
受保护的抽象字符串produceSound();
受保护的静态地图声音列表;
受保护的静态布尔寄存器声音(字符串声音,字符串类型)
{
return(SoundList.insert(pair(sound,type))->second;//如果工作,则为true;如果已经存在,则为false
}
受保护的静态字符串识别动物(字符串动物声音)
{
map::iterator result=SoundList.find(声音);
if(result!=SoundList.end())
返回结果->秒;
其他的
返回“这到底是什么!?”;
}
}
猫类
公营猫科动物
{
猫()
{
动物::登记声音(“毛”,“猫”);
}
@凌驾
受保护的字符串produceSound(){
还“毛”;
}
}
抽象类动物{
静态映射映射=新的HashMap();
公共动物(字符串值){map.put(produceSound(),value);}
受保护的抽象字符串produceSound();
受保护的静态空洞识别动物(字符串动物声音){
System.out.println(map.get(animalSound));
}
}
猫科动物{
@凌驾
受保护的字符串produceSound(){返回“Mao”;}
Cat(){super(“Cat”);}
}   
类狗扩展动物{
@凌驾
受保护的字符串produceSound(){返回“Bao”;}
Dog(){super(“Dog”);}
}   
课堂测试{
公共静态void main(字符串[]args){
新狗();
新猫();
动物。识别动物(“Bao”);
}    
}

是否希望dog.IdentificationAnimal(“Mao”)返回。。。猫或猫这个词的例子?也许狗不应该知道关于猫的任何事情。但是,如果它只知道“宝”,那么你真的在问,布尔狗。你的声音(“宝”);静态方法在任何情况下都不适用。只是想知道,猫说毛和狗说宝在哪个国家?@Radu在你以南的国家。@nnnnnn这经常发生,不是吗;)除了硬编码之外,我想不出任何优雅的方法来做这件事<代码>如果(sound.equals(“Mao”){returnnewcat();}
。。。顺便说一句,我们的猫“Miau”和我们的狗“Hau”。你的方法应该有一个字符串参数,而且不应该是静态的,我猜只要读一下Java标记……可能会使用Manishs解决方案,或者一个组合,注册类而不是字符串。虽然这仍然有一个毫无价值的开销问题(在第一个注册表/类之后)可能会将您的开销与@AdamReed结合起来,但解决方案是golden middleWhoops没有看到Java标记,我假设C#