Thursday 12 January 2012

Overridding Method Rules in Java


The rules for overriding a method are as follows: 
 
1) The argument list must exactly match that of the overridden method. If they don't match, you can end up with an overloaded method you didn't intend.

Example :
 class Base{
public void add(int x,int y){
}
}
class Sub extends Base{
public void add(float x,float y){
}
}
Where Sub class overloads the add(int,int) method.If you want to override the Base class add(int,int) method declare the method as given below.

class Sub extends Base{
public void add(int x,int y){
}
}


2) The return type must be the same as, or a subtype of, the return type declared in the  original overridden method in the superclass(covariant returns.)

Example :

class Base{
public void fun(){ //Line 2
}
}
class Sub extends Base{
public int fun(){ //Line 6
}
}
Here you will get a compile time error that The return type is incompatible with Base.fun() at Line 6.It won't even act as an overloaded method because by simply changing return type can't overload one method.

For overriding a function, if the return type of the base class function is a primitive type (i.e. void,byte,short,int,long,flat,double,boolean,char) then sub class function should also be with the same return type.

If the return type of the function is an object reference then there is a little difference in the rule from java 1.5. 
 
Example :

class Alpha {
Alpha doStuff(char c) {
return new Alpha();
}
}
class Beta extends Alpha {
Beta doStuff(char c) { // legal override in Java 1.5
return new Beta();
}
Here doStuff(char c) is a legal override method if you are using java 1.5 or above for running it.From java1.5 the return type must be the same as, or a subtype of, the return type declared in the original overridden method in the superclass.
 
3) The access level can't be more restrictive than the overridden method's.

Example: 

class Base{
public void fun(){ //Line 2
}
}
class Sub extends Base{
void fun(){ //Line 6
}
}
Here you will get a compile-time error at Line 6 that  Cannot reduce the visibility of the inherited method from Base.The access level can be less restrictive or same as that of the overridden method.

The access level restrictions from high to low is
  • private ( cant use for overriding)
  • default or package level
  • protected
  • public
i.e. If the base class method has default access then default,protected and public access levels are valid for sub class function.In our example you should use public access level for overriding method fun().

class Base{
public void fun(){ //Line 2
}
}
class Sub extends Base{
public void fun(){ //Line 6
}
}

4) Instance methods can be overridden only if they are inherited by the subclass. 

Remember that overriding implies that you're reimplementing a method you inherited.
A subclass within the same package as the instance's superclass can override any superclass method that is not marked private or final.

class Base{
private void fun(){ //Line 2
}
}
class Sub extends Base{
public void fun(){ //Line 6
}
}
The above example is legal but Sub class fun() is not the overriding method of Base class fun() because private method fun() can’t be inherited from Base to Sub class.

A subclass in a different package can override only those non-final methods marked public or protected (since protected methods are inherited by the subclass).

Package p1;
Public class Base{
void fun(){ //Line 3
}
}

Package p2;
Import p1.Base;
class Sub extends Base{
void fun(){ //Line 4
}
}

The above example is legal. But fun() in Sub is not the overriding method of fun() in Base.Since the Base class fun() has package level access ,it is not visible to package p2.

5) The overriding method CAN throw any unchecked (runtime) exception,regardless of whether the overridden method declares the exception. 
 
class Base{
public void fun(){ //Line 2
}
}
class Sub extends Base{
public void fun() throws ArithmeticException{ //Line 6
}
}

The above example is valid because ArithmeticException exception is a runtime exception.The overriding method can throw one or more runtime exceptions even if the base class function is not throwing it.

6) The overriding method must NOT throw checked exceptions that are new or broader than those declared by the overridden method. The overriding method can throw narrower or fewer exceptions.

Example:

class Base{
public void fun() throws IOException{
}
}
class Sub1 extends Base{
public void fun() throws FileNotFoundException
// Valid because FileNotFoundException is the sub class of IOException (narrowing). 
}
}
class Sub2 extends Base{
public void fun() throws IOException{

//Valid because using same exception as that in base class function's throws clause.
}
}
class Sub3 extends Base{
public void fun(){
//Valid because overriding method can throw fewer or no exceptions.
}
}
class Sub4 extends Base{
public void fun() throws SQLException{
//Not valid because SQLException is a new exception .It is not compatible with IOException.
}
}
class Sub5 extends Base{
public void fun() throws Exception{
//Not Valid because Exception is the base class of IOException (broadening).
}
}
 
7) You cannot override a method marked final.

class Base{
final public void fun(){ //Line 2
}
}
class Sub extends Base{
public void fun(){ //Line 6
}
}

You will get compile-time error at Line 6 saying Cannot override the final method from Base.


8) You cannot override a method marked static.

class Base{
public static void fun(){
}
}
class Sub extends Base{
public static void fun(){
}
}

The above example is valid but Sub class static fun() is not the overriding method of Base class static fun().

Ie Base b=new Sub();
    b.fun();
Here b.fun(); invokes the Base class fun() not the sub class fun() (in case of non static method it will invoke Sub class fun() ).
 


1 comment: