2012-03-11 65 views
3

它可能看起來像你的僞問題,但我有困難解決這個:簡單的面向對象的編程概念

我們有一個抽象class AnimalCat和延伸它Dog。在Animal我們有一個方法produceSound();是抽象的。正如你可能已經猜到了Cat它應該返回「毛」和Dog - 「寶」或類似的東西。這是確定的,但現在我們必須寫一個返回取決於他們的聲音CatDog對象Animal class一個static方法。例如:identifyAnimal("Mao")應該返回Cat

問題:如何實施identifyAnimal(String sound)方法?

下面是層次結構的一些簡單的例子:

動物類

public abstract class Animal { 

    protected abstract String produceSound(); 

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

Cat類

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類調​​用Animal.identifyAnimal("Bao");我們應該得到一個Dog時。

+0

你想dog.identifyAnimal( 「毛」)返回...貓的一些實例或字貓?也許狗不應該知道關於貓的任何事情。但是如果它只知道「寶」,那麼你真的在問,布爾dog.isYourSound(「寶」); 靜態方法是沒有任何實例。 – 2012-03-11 02:04:11

+0

想知道,貓在哪個國家說毛和狗寶? – rid 2012-03-11 02:04:54

+0

我剛剛編輯過這個問題。 – nyxz 2012-03-11 02:04:54

回答

2
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; 
} 
+0

願你與@ AdamReed的解決方案來合併是金色的中間 – nyxz 2012-03-11 02:31:40

0

做與你,讓每個聲音返回一個字符串,用動物的名字預定義的聲音的開關。例如,「毛」返回一個字符串「貓」等。 還有一兩件事讓烏爾identifyAnimal方法returna字符串,而不是無效的。

+0

你的方法應該有一個字符串參數偏離航向,不應該是靜態的我猜 – 2012-03-11 02:09:53

0

您可以使用反射來獲取擴展Animal的所有類型的列表,使用Activator循環它們以創建每個運行produceSound的每個類型的實例,直到找到與animalSound匹配的返回值,並返回該實例。如果你想避免你的動物類意識到擴展它的內容,那麼速度緩慢但很有效。

+0

哎呦沒有看到Java標記,我是假設C# – 2012-03-11 02:57:41

0

您試圖解決的問題的性質是什麼?沒有與問題無關的「正確」方式。

什麼是消費類應用需要Animal?你的應用程序需要使用它所使用的類是什麼?除非這些推定是明確的,否則不能假定。

2

所以這裏有一個(可怕的)方法來做到這一點。我實際上抽動了一下。 我不知道你在用什麼語言,所以我會用C++(抱歉,當前模式),儘管你可以用Dictionarys替換地圖,如果我們在C#中,無論如何。這是一個不好的方法去做事,但應該工作(在概念上,無論如何)

再次...可怕......

公共抽象類動物{

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"; 
    } 
} 
+0

剛讀Java標籤...可能會與Manishs解決方案然後 – 2012-03-11 02:27:18

+0

或組合,註冊Classes而不是字符串。雖然這仍然存在無用的開銷問題(在第一次註冊表/課程之後) – 2012-03-11 02:30:48

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