Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overriding Methods constraints in java

Overriding Methods in java have the following features :

1> The Overrinding method should have the same argument list as the Parent class method.

2> The return type should be the same/subclass of the return type for the parent class method.

3> The access level should be same or less restrictive as the parent class method.

4> The overriden method can throw the same or Narrower exception and not a broader one.

*Just wanted to know why is it so for point *

*2 - why subclass why not a superclass?*

3 - why the access level should be less restrictive?

4 - why it should throw narrow exception?

As per my understanding its just that if i am creating a parent class refrence to create a child class object and trying to run down each of the scenario then

Lets assume A is parent class and B is child class both having method printAndReturnSomething()

public class A{

       public B printAndReturnSomething(){
                S.O.P("Inside A Print");
                return new B();
              }
}

Now we have the child class B as

public class B extends A{
       public A printAndReturnSomething(){ // I know this isn't possible to return A but had it been then
                S.O.P("Inside A Print");
                return new A();
              }
}

Now if i do something like this

A a =new B();

and now as i have a reference of A so i expect the return type to be of type B

B returnedValue=a.printAndReturnSomething(); // But it actually calls the child class method and hence returns A. So here comes the contradiction.

Similaraly for the scenarios 3 and 4. Is my understanding correct? Am i missing something else more relevant?

like image 879
Deva Avatar asked Sep 07 '11 20:09

Deva


1 Answers

All of this can be summarized by saying that "a subclass has to behave as if it was a superclass". So if Derived extends Base and I have an object x of type Derived, then I want it to behave exactly as if it were of type Base.

So if x.foo() returns some type T, and Base::foo() returns a type S, then I want to be able to treat x.foo() as an S, so T better be the same as or a subclass of S.

Similarly, x.foo() should only throw exceptions that Base:foo() promises. It can't start throwing new, unexpected exceptions.

If Base::foo() is public, then so should x.foo() be. You can't suddenly have a tighter restriction on the derived class, because the base class promised me that it was public.

Always think of inheritance as "behaves like the super class", or "can be treated like the superclass", and all this should be clear.

like image 133
Kerrek SB Avatar answered Oct 03 '22 15:10

Kerrek SB