0

I have two classes, Dog and Cat:

class Dog{
   public void speak(){
        System.out.print("Woof!");
   }
}

class Cat{
   public void speak(){
       System.out.print("Meow!");
   }
}

In my main, I take the name as String, either "Cat", or "Dog".

public static void main(String [] args){
    Scanner sc = new Scanner(System.in);
    String name = sc.next();

    Class<?> cls = Class.forName(name);
    Object object = cls.newInstance();
}

But now I want to be able to call the method "speak". But then I have to cast the object to either cat or dog, since "Object" obviously does not have built in "speak" method. So my solution was to make another class (I can't use if-statements btw):

class Animal{
    public void speak(){
    }
}

And then both "Cat" and "Dog" can extend Animal and override its methods. Is there any other way to do this WITHOUT making another method / using if-statements? (Including switch case, ternary operator). Thanks in advance.

ANOTHER QUESTION: If I take in the name of the METHOD in as an input as well, how would I call it? For example:

class Dog{
    public void speak(){}
    public void bark(){}
}

If I take in as a String either "speak" or "bark", how would I call the method without using if-statements?

2
  • Didn't you just answer yourself? Just use the baseclass Animal and override speak(). Where do you need a control structure? Commented Dec 1, 2013 at 3:44
  • I don't want to create another class. I wanted to know if there were any way to do without it. Commented Dec 1, 2013 at 3:45

4 Answers 4

2

You can do it with reflection using Class.getMethod and Method.invoke.

Creating an Animal class is really the cleanest way, though. What stops you from doing that?

Sign up to request clarification or add additional context in comments.

Comments

0

You are on the right track. The easiest way is to create an animal class and have dog and cat inherit from it and make them both implement their own version of speak(). Is there a reason you don't want to create another class?

Comments

0

You don't have to create class Animal - create an interface:

interface Animal{
    public void speak();
}

and have both Cat and Dog implement it. Then in main():

Class<?> cls = Class.forName(name);
Animal animal = cls.newInstance();
animal.speak();

No need to cast or use if/else.

The only reason to use inheritance/abstract classes is when you want to reuse functionality (implement a method once and use it in a few classes). Otherwise - better use interfaces.

As for the method name, if you want the "wise-ass" solution: use switch (supported from Java 7). Otherwise, see @immibis's answer.

Comments

0

Alright, here are two methods ordered by preference:

abstract class Animal {
    public abstract void speak();
}

class Dog extends Animal {
    @Override
    public void speak() {
        System.out.println("Woof woof");
    }
}

class Cat extends Animal {
    @Override
    public void speak() {
        System.out.println("Miauw");
    }
}

public static void main(String[] args) {
    String type = "Dog";
    Class<?> clazz;
    try {
        clazz = Class.forName(type);
        Animal pet = (Animal) clazz.newInstance();
        pet.speak();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

I'm using a baseclass since it can be assumed that an Animal will hold more fields that are shared by each animal (name, species, etc). If this isn't the case then you should go for an interface.

Or with reflection:

public class Test {
    public static void main(String[] args) {
        String type = "Dog";
        Class<?> clazz;
        try {
            clazz = Class.forName(type);
            for(Method method : clazz.getMethods()){
                if(method.getName().equals("speak")){
                    method.invoke(clazz.newInstance(), null);
                }
            }
        } catch (CException e) {
            e.printStackTrace();
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.