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 (theFatherpotentially throws an exception that will never happen). - Use a
RuntimeExceptioninstead? This solution won’t propagate theExceptionto theFather, 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 useRuntimeExceptioninstead?). - Other..
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. Methodmethod()ofFatherwill throw it. The defineChildException extends BaseExceptionand declaremethod1()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
IOExceptionandFileNotFoundExceptionthat extends it. You can work with input stream catchingIOExceptionwhile the concrete stream isFileInputStreamand it throwsFileNotFoundException. But client does not know this. It catchesIOException.