dblh90
dblh90

Reputation: 173

Implementing a method which is declared in an interface and parent class

I have a little dilemma here,

say I have a class

public class Child extends Parent implements Interface{
 public static void main(String[] args){
  Child child = new Child();
   child.methodOne(); } }

where

abstract class Parent {

public void methodOne()  {
    System.out.print("cannot fly ");
}}

interface Interface {
public abstract void methodOne() throws Exception;}

There are no compilation errors with this structure

wherease if I did this

abstract class Parent {

public void methodOne() throws Exception {
    System.out.print("cannot fly ");
}}

interface Interface {
public abstract void methodOne(); }

Two compliation errors rise saying

Exception Exception in throws clause of Parent.methodOne() is not compatible with Interface.methodOne()

and

Unhandled exception type Exception

which asks to add throws or try/catch in main method

Why is that happening?

Upvotes: 1

Views: 1143

Answers (3)

shan
shan

Reputation: 288

When you are doing this,

public class Child  extends Parent implements Interface
  • Parent class is implementing the Interface.
  • methodOne in Parent class becomes the overridden method.
  • Child which is extending Parent class, don't see this exception.

But, when you are explicitly throwing an exception in the Parent class' method, you have to handle that exception when you make a call from the child object.

Upvotes: 3

secolive
secolive

Reputation: 589

Every time you implement an interface (or override a method from a parent class, same thing), you need to respect the contract of that interface. Respecting the contract means that you cannot throw more exceptions than in the interface declaration.

In both cases, Interface is the contract, and Parent is the implementation (via the "binding" between the two that happens in class Child).

In the first case, the interface says that methodOne() is allowed to throw Exception, but does not have to. Your actual implementation in Parent does not throw anything, so it is a subset of the contract and is fine.

In the second case, the interface says that methodOne() will not throw anything (*), hence any implementation consequently is not allowed to throw any exception. However, the implementation in Parent asks to be allowed to throw, which is incompatible with the interface contract; hence the compiler error.

Also note in this second case that you could very well override methodOne() in Child with an empty throws declaration so that the signature would conform to the interface contract. You could then call super.methodOne() and rewrap Exception as RuntimeException (for example).

By the way:

  • if you implement multiple interfaces with the same method signatures, the implementation can throw only the intersection of throws declaration of all interfaces;
  • you don't need to use the abstract keyword in interfaces, because method declarations in interface are always abstract by nature.

(*) except for RuntimeException's of course.

Upvotes: 4

Blake Yarbrough
Blake Yarbrough

Reputation: 2316

The throws declaration is not part of the methodOne() contract in the interface Interface.

Whenever you implement an interface you must implement your method contracts, you can do this without adding the throws declaration if the interface has a throws declaration.

However you cannot add functionality that isn't stated in the Interface contract.

You can fix the other error by modifying your main method to also throw an Exception:

 public static void main(String[] args) throws Exception {
  Child child = new Child();
   child.methodOne(); 
 }

or by surrounding the methodOne() call in a try-catch block:

 public static void main(String[] args) throws Exception {
  Child child = new Child();
   try{
       child.methodOne(); 
   }catch(Exception e){
      //do something to handle exception i.e. System.out.println(e.getMessage());
   }
 }

Additional reading: Java interface throws an exception but interface implementation does not throw an exception?

Excerpt:

A general rule of implementing and extending is you can make your new class or interface "less restrictive" but not "more restrictive". If you think of the requirement to handle an exception as a restriction, an implementation that doesn't declare the exception is less restrictive. Anybody who codes to the interface will not have trouble with your class.

Upvotes: 1

Related Questions