nyxz
nyxz

Reputation: 7438

Simple Object-oriented Programming Concepts

it may looks like a dummy question for you but I have difficulties solving this:

We have an abstract class Animal and Cat and Dog that extends it. In Animal we have a method produceSound(); that is abstract. As you can probably guess for Cat it should return "Mao" and for Dog - "Bao" or something like that. This is OK but now we must write a static method in the Animal class that returns Cat or Dog objects depending on their sound. For example: identifyAnimal("Mao") should return Cat.

Question: How to implement the identifyAnimal(String sound) method?

Here is some simple example of the hierarchy:

Animal class

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

Dog class

public class Dog extends Animal{

    @Override
    protected String produceSound() {
        return "Bao";
    }
}  

Test class

public class AnimalTest {

    public static void main(String[] args) {
        Animal.identifyAnimal("Bao");
    }
}  

In the AnimalTest class when calling the Animal.identifyAnimal("Bao"); we should get a Dog.

Upvotes: 4

Views: 3376

Answers (6)

Adam Reed
Adam Reed

Reputation: 3314

So here a (terrible) way to do this. I actually twitched a little. I don't know what language you are using, so I'm going with c++(sorry current mode) though you could replace maps with Dictionaries if we are in C#, whatever. This is a bad way to go about things, but should work(conceptually, anyway)

Again...Terrible...

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

Upvotes: 2

Java42
Java42

Reputation: 7716

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

Upvotes: 1

Manish
Manish

Reputation: 3522

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

Upvotes: 4

Tom W
Tom W

Reputation: 5423

What is the nature of the problem you are trying to solve? There is no 'right' way that is independent of the problem.

What does the consuming application need from the class Animal? What does your application need to do with the classes that it consumes? Nothing can be assumed unless these presumptions are clear.

Upvotes: 0

Chris Ray
Chris Ray

Reputation: 5003

You could use reflection to get a list of all types that extend Animal, loop through them using Activator to create instances of each type running produceSound on each until you find the return value that matches animalSound, returning that instance. Slow, but effective if you want to avoid your Animal class being aware of what extends it.

Upvotes: 0

Alex
Alex

Reputation: 6159

Do a switch with the predefined sounds that you have and let each sound return a string with the name of the animal. For example "Mao" returns a string "Cat" and so on. One more thing let ur identifyAnimal method returna string instead of void.

Upvotes: 0

Related Questions