Inheritance , method signature , method overriding and throws clause

11,078

Solution 1

No, this is appropriate - an overridden method can be more restrictive about what it throws (and returns) because this can be useful for callers who know at compile time that they'll be using the overridden method, and don't want to bother with exceptions which can't happen etc. It has to be more restrictive rather than more permissive though, so that it can't surprise callers who do access it through the parent declaration.

Using the overridden method via a reference of type Parent is never going to violate the contract of "it might throw IOException" - the absence of an exception doesn't violate the contract. The other way round (if the parent didn't declare the exception, but the overriding method does) would be a contract violation.

Solution 2

Easy to remember

  1. Access modifier can be changed from restricted to less restricted,
    for example from protected to public, but not vise versa
  2. throws signature can be changes from parent exception to child exception class, but not vise versa

This code is valid

public class A  {

    protected String foo() throws Exception{
        return "a";
    }

    class B extends A {
        @Override
        public String foo() throws IOException{
            return "b";
        }
    }
}

Overrided foo method has public access, not protected and throws IOException that child of Exception

This code is not valid

public class A  {

    public String foo() throws IOException{
        return "a";
    }

    class B extends A {
        @Override
        protected String foo() throws Exception{
            return "b";
        }
    }
}

Overrided foo method has more restricted access modifier and throws Exception that NOT child of IOException

By the way you can override method from superclass and not throw ecxeptions at all

This code valid

public class A  {

    public String foo() throws IOException{
        return "a";
    }

    class B extends A {
        @Override
        public String foo(){
            return "b";
        }
    }
}

Solution 3

Well, the overriding method might not throw any exception at all (or at least fewer exceptions), thus you can remove exceptions from the throw clause (or the throw clause as a whole).

Suppose the overriding method catches all exceptions, logs them and returns a special value. Although that's not good style (it would change the semantics of the method) it is still possible andd thus you'd not have to catch exceptions that are never thrown if you know at compile time that you're dealing with a Child.

Adding exceptions won't work, since users of the class who access it through the Parent reference don't know of any exceptions that Child might add.

Solution 4

You have the freedom to override a method without the throws keyword, because if you want to develop a method by controlling all the exceptions, then you can do that by overriding the method without any throws clause.

But remember one thing that if you want to include the throws clause in the subclass method, then the throws clause must associate with the exception which must be the same or the subclass of the exception what is thrown by its superclass method. for example-

class Super{
    void a()throws IOException{
        ......
    }
}
class Sub extends Super{
    void a()throws IOException{
        ......
    }
}

The a() method of class Sub must throw IOException or any subclass of IOException, otherwise compiler will show error.

That means if you write

void a()throws Exception

in the class Sub, then it will cause compilation error.

Share:
11,078
AllTooSir
Author by

AllTooSir

Updated on June 05, 2022

Comments

  • AllTooSir
    AllTooSir almost 2 years

    My Parent class is :

    import java.io.IOException;
    public class Parent {
            int x = 0;
            public int getX() throws IOException{
            if(x<=0){
             throw new IOException();
            }
           return x;
          }
     }
    

    I extend this class to write a subclass Child:

    public class Child1 extends Parent{
         public int getX(){
            return x+10;
       }
    }
    

    Notice while overriding the getX method in the Child class , I have removed the throws clause from the method definition .Now it results in an anomalous behavior by the compiler which is expected :

    new Parent().getX() ;
    

    does not compile without enclosing it in a try-catch block , as expected .

    new Child().getX() ;
    

    compiles without enclosing it in a try-catch block .

    But the below lines of code needs the try-catch block .

    Parent p = new Child();
    p.getX();
    

    As this could be foreseen i.e. using a parent class reference to invoke a child method during run-time polymorphism , why the designers of Java didn't make it mandatory to include the throws clause in the method definition while overriding a particular parent class method ? I mean if a parent class method has throws clause in its definition , then while overriding it the overriding method should also include the throws clause , Ain't it ?

  • AllTooSir
    AllTooSir about 12 years
    Thanks for enlightening me :)
  • Aseem Bansal
    Aseem Bansal over 9 years
    so that it can't surprise callers who do access it through the parent declaration. This really helped me understand the reasoning.
  • saiki4116
    saiki4116 over 8 years
    This helps, got destroyed in interview because of this question.