interface A{
void f() throws FillInStack;
}
abstract class Abs{
abstract public void f() throws MyExc;
}
class interface_excep extends Abs implements A{
@Override
public void f(){ }
}
Above code compiles with no error. FillInStack and MyExc are simple classes derived from Exception
I have even used function f() in two different exception cases that gives no error...
1st Case:
A a=new interface_excep();
try{
//...
a.f();
}
catch(FillInStack m){
//...
}
2nd Case:
Abs a=new interface_excep();
try{
//...
a.f();
}
catch(MyExc m){
//...
}
But when I tries to throw exception from the function f() it gives error.
public void f() throws MyExc{ //! Error
//...
throw new MyExc();
//...
}
I know that changing name of method f() from both interface A and abstract class Abs will solve the problem. But what if I Derive my class from an interface and abstract class provided to me by some vendor library and got into the similar situation, then how will I throw any exception from this function???
Does Java have any implicit solution for this or simply we must have two function with different name???
Edit:
Code for the above two exception...
class MyExc extends Exception{ }
class FillInStack extends Exception{ }
Because f
has two different signatures, you are in crazy-land trying to inherit both versions. When you declared A a=new interface_excep();
(non-compliant type name!) you tell the compiler that a
is of type A
, which is why it recognizes that exception toss in the catch
. Likewise with Abs a=new interface_excep();
(non-compliant type name!) you tell the compiler that a
can throw the other exception. But when you try to define public void f() throws MyExc
in a class that inherits both A
and Abs
, you're adding a restriction that A
does not recognize, which violates the override regulations. So you can't do that, nor can you override it to throw FillInStack
because that violates the contract from Abs
. So you can (and actually must) catch either exception, depending on the compile-time type of the variable, but you can never throw either one.
You've intentionally set up incompatible contracts so that no implementing class can fulfill both. So no, you won't get away with that.
Per the Liskov Substitution Principle, any subtype must fit where its supertype does. That means the override can declare fewer throws
exceptions, but never more than its supertype. So you either need to fix up the interface to allow both exceptions, or forget about it.