1

I am writing a program that demonstrates the use of inheritance and overriding methods. I want to create an if statement that involves the use of an exception. I ave included the exception in my if statement but when I write "throws exception" a the beginning of the method, I m getting n error message that says ""overridden method does not throw Exception". Here is the code:

Sub class

public class Carnivore extends Animal
{
   public Food eat(Food x) throws Exception
    {
        if (x.equals("Plants")) {
                throw new Exception("Carnivores only eat meat!");
            } else {
                return x;
            }

    }
    public void makeNoise()  
    {
        noise = null;
    }
    public String getNoise()  
    {
        return noise;
    }   
}

Super class

abstract public class Animal {

String name;
int age;  
String noise;

abstract public void makeNoise();

public String getName() {
        return name;
    }

    public void setName(String newName) {
        name = newName;
    }

abstract public Food eat(Food x);

}

Any help on how to re-write this so that the exception is thrown properly is appreciated, thanks.

Ben
  • 153
  • 1
  • 9
  • 1
    Either add the throws clause to the superclass or remove it from the subclass. – chrylis -cautiouslyoptimistic- Nov 23 '16 at 01:41
  • there are too many relevant questions on stackoverflow like [Exception and Inheritance in Java](http://stackoverflow.com/questions/12978798/exception-and-inheritance-in-java) – nail fei Nov 23 '16 at 01:55
  • The rule is simple. You shouldn't break the existing callers. Imagine if you add a subclass that throws a new exception, all the existing callers didn't handle and will be freaked out. This is not allowed. You should add 'throws Exception' in the parent class, so that all callers will be aware of that in the first place. – Man Coding Sep 06 '19 at 10:09

3 Answers3

0

Since you should be able to safely substitute any subclass for a supertype instance, you can't add checked exceptions that aren't in overridden methods. In this case, you could either add throws Exception to your Animal#eat(Food) method or remove it from Carnivore.

However, it's almost always a bad idea to actually throw just a plain Exception class; there are lots of individual classes that carry meaning. In your case, you should throw an IllegalArgumentException, which is the proper type when a method invocation fails because the arguments provided aren't suitable. This is an unchecked exception and will not need a throws clause.

Note that x.equals("Plants") is almost certainly the wrong approach for the check. Either provide Food with a type() method that returns an enum value, so x.type() == Foods.PLANTS, or provide a boolean isPlant() method, so x.isPlant().

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
0

As per your code you have mentioned that the implemented method eat(Food x) can throw an Exception which is java.lang.Exception. This java.lang.Exception is Super class of all Exception classes in the exception hierarchy. So it is excepting both checked as well as Unchecked exception. According to overriding rule if Super class method does not throws any exception, while overriding the method in child class you can throw RunTimeExceptions.

So as per your code supper class method is

abstract public Food eat(Food x);

the above method does not throws any exception

so while overriding it in child class if you write below code you will get compile time Exception

public Food eat(Food x) throws Exception
{
    //do your work
}

but it can be done as below.

public Food eat(Food x) throws RunTimeException
{
}

Hope you got the answer.

Majenko
  • 1,816
  • 18
  • 27
  • No, throwing runtime is a separate topic. Exception class is checked exception. You have a proper handling in your mind. Changing it to RuntimeException which is an uncheck exception doesn't make a lot of sense. Runtime exception is thrown when you don't expect any handling, it is totally unexpected and I don't have a idea how to handle. – Man Coding Sep 06 '19 at 10:15
-1

You have to respect the signature in your inheritance and checked exceptions is part of method signature in Java.

Since you didn't defined that the 'Exception' may be thrown in your super class. Carnivore cannot thrown exception as well. So if you method is supposed is design to eventually thrown exception - define it in your super class as well.

Another possibility is to work with Runtime Exception which can fit in this kind of flow. For instance you can remove throws Exception and replace Exception to illegalArgumentException - which is a Exception more suitable for this purpose.

Example:

public Food eat(Food x) {
    if (x.equals("Plants")) {
      throw new IllegalArgumentException("Carnivores only eat meat!");
    } else {
      return x;
    }
  }
  • *"checked exceptions is part of method signature in Java"*: https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.2 – Tom Nov 23 '16 at 02:01