To help me learn it better, can anyone explain to me why a overriding method in a subclass can only throw the same exception or children of the exception in the parent class? Why could we throw a different exception since the overriding method maybe doing a different "risky" operation.
It all has to do with polymorphism, which says that any time a certain object is needed, a subtype of that object will do just fine.
So, a parent has a method, and somebody calls that method, with the exception that a couple of exceptions could be thrown, and of course, those exceptions are handled. But at runtime, what happens if a subclass, or subtype is provided instead of the parent? No problem right, because any time an object is needed, any subtype will do just fine.
But what happens if your subtype starts throwing all these crazy, obscene and simply vile exceptions? The original program had no idea that the child would be so obtuse, and the exceptions would never be handled, causing all sorts of programming problems.
Well, this scenario can never happen in Java, becuase the rule says that no child can throw any crazy exceptions that aren't declared in the overridden method from the parent class. It all has to do with polymorphism, and allowing a class to be coded based on expected behavior.
It's simple: because a subclass "is-a" instance of the superclass, and may be treated as such. Imagine a class A with a method m() that throws exception type EA. Then further imagine a subclass B with a method m() that declares that it throws the unrelated exception type EB. Now look at this code:
Now: what happens if B.m() throws EB? Note that there's no catch block for catching EB, and the compiler doesn't force you to create one, since the method being called -- as far as the compiler is concerned, is A.m(). So the exception would be thrown, and completely surprise the caller! The exception would go uncaught and perhaps terminate the program.
So that's why this is not allowed: B.m() is not allowed to throw EB, but only EA or subclasses of EA.
It's not quite legal. Because the variable is of type P, the compiler thinks that the call to m() could throw EP. You could include two catch blocks, one for each type, with EC coming first; but you can't neglect to catch EP unless the call is made via a variable of type C.