Skip to content

Latest commit

 

History

History
57 lines (41 loc) · 2.05 KB

74d2.md

File metadata and controls

57 lines (41 loc) · 2.05 KB

Back to questions

Solution to 74d2: Exceptions and inheritance (i)

See code at solutions/code/tutorialquestions/question74d2

Classes A and B do compile. The potential reason for which I was hoping you might have thought they would not compile was the fact that A declares a method foo with the following signature:

public void foo() throws Exception;

while B attempts to override foo with a different signature:

@Override
public void foo();

The difference is that foo in A throws Exception while foo in B does not throw any exception. This is OK, however: it is permissible for an overridden method to throw a narrower type of exception than the exception specified in the superclass, or (as in this case) to throw no exception at all.

The way to think about this is that it is OK for the overridden method to behave better than the superclass method. Client code that uses the superclass must be prepared to deal with any exceptions the superclass method may throw. If at runtime an instance of the subclass, whose method behaves better, is present, this is no problem. (Do you see why the rule therefore could not be the other way around? I.e., why wouldn't it make sense to allow subclass methods to throw more, or more general exceptions than the superclass specifies?)

Changing to body of foo in B from:

@Override
public void foo() {

}

to:

@Override
public void foo() {
  super.foo();
}

leads to a compilation error. The reason is that super.foo(); requests that method foo in A is called. However, this method may throw an Exception, which foo in B would have to deal with, but does not.

This problem can be solved either by changing foo in B to throw Exception, so that if foo in A does throw an Exception this is propagated by foo in B, or by enclosing the call to super.foo(); in a try...catch block:

@Override
public void foo() {
  try {
    super.foo();
  } catch(Exception e) {
    // Do something
  }
}