11

Suppose we have this problem

public class Father{
    public void method1(){...}
}

public class Child1 extends Father{
    public void method1() throws Exception{
    super.method1();
    ... 
    }

}

Child1 extends Father and overrides method1 but given the implementation Child1.method1 now throws a exception. This won't compile as the overriding method can't throw new exceptions.

What is the best solution?

  • Propagate the required exception to the Father. To me this is against encapsulation, inheritance and general OOP (the Father potentially throws an exception that will never happen).
  • Use a RuntimeException instead? This solution won't propagate the Exception to the Father, but Oracle docs and other sources state that class of exceptions should be used when "Client code cannot do anything". This is not that case, this exception will be useful to recover blablabla (why is it wrong to use RuntimeException instead?).
  • Other..
1
  • thanks for sharing your thoughts people, now more or less I know what I need to do next time I find this kind of problem Commented Oct 19, 2012 at 17:38

5 Answers 5

4

Using RTE is not a bad idea. This is the methodology of Spring framework and it works quite fine. If you are implementing application probably use this solution.

If however you are implementing library that exposes API IMHO you should use checked exception. In this case you should create your own exception for example BaseException. Method method() of Father will throw it. The define ChildException extends BaseException and declare method1() of child class to throw it.

This does not break encapsulation: base class throws base exception. It does not have any idea about the concrete exception. Child class throws concrete exception that however extends base exception and therefore can be treated by client code as base exception.

As an example I can give you IOException and FileNotFoundException that extends it. You can work with input stream catching IOException while the concrete stream is FileInputStream and it throws FileNotFoundException. But client does not know this. It catches IOException.

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

1 Comment

yes I understand, I just didn't feel comfortable adding the throws to the Father, I don't like the idea of the Father adding something cause the Child does require it. thanks!!
2

Depends on what throws the Exception in Child1. If its some preconditions etc, you can always use any of the subclasses of RuntimeException such as IllegalArgumentException.

However, if there is some sort of CheckedException, then logic suggests that you should handle it that method itself and bubble up the message in some other way.

I think the general rule of thumb is that

if you know how to handle it.. use a checked exception else unchecked exception

1 Comment

This is a good answer, because the child knows that it might throw, so it should also catch it and not leak that into the parent's signature. It might be code that you don't control (e.g. from a library) that throws the checked exception in the child. If you need to handle the failure, and cannot do that in the child itself, then return it as a message (simplest might be a documented boolean: success or failure), so that the parent knows that the child didn't successfully do its job.
2

If super class method does not declare an Exception then subclass overridden method can not declare checked exception. So you can only use Unchecked exception.

Other option is to allow Super class to declare ParentException and then child overridden methods can declare any exceptions which are child of ParentException

Comments

0

The "throws" part is a part of the method signature.
This is why the method at the "child" class is not an override of the method of the parent class.

Comments

0

Propagate the required exception to the Father.. to me this is against encapsulation, inheritance and general OOP ( the father potentially throw and exception that will never happen )

Au contraire: This is good OO. Image the caller side:

Father f = factory.getSomeImplementation();
f.method1();
// user has no chance to see the `Exception` of Child coming...

The factory can return an instance of Father or Child or something completely different like Brother. But the contract of method1 must be the same in all cases. And this contract includes checked exceptions. This is the Liskov substitution principle, one of the basic rules of OO.

So if the exception is part of the business contract of method1 it must be declared at the root. If it is not (e.g. a simple argument check) then a RuntimeException is the route to go anyways (i.e. even without inheritance).

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.