Overloading And Overriding Rules

Overriding Rules

  • The argument list must exactly same that of the overridden method. If they don't match, you can end up with an overloaded method.
  • The return type must be the same as, or a subtype of, the return type declared in the original overridden method in the superclass (also called covariant return type).
  • Instance methods can be overridden only if they are inherited by the subclass.
  • A subclass within the same package as the instance's superclass can override any superclass method that is not marked private or final. 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).
  • The overriding method can throw any unchecked (runtime) exception, regardless of whether the overridden method declares the exception.
  • The overriding method must not throw checked exceptions that are new or broader than those declared by the overridden method. For example, a method that declares a FileNotFoundException cannot be overridden by a method that declares a SQLException, Exception, or any other non-runtime exception unless it's a subclass of FileNotFoundException.
  • You cannot override a method marked final.
  • You cannot override a method marked static.
  • If a class is not inherited, you cannot override its methods.

Overloading Rules

  • You can overload a method by changing its signature. method signature is made of number of arguments, type of arguments and order of arguments.
  • Return type is not a part of method signature, so changing method return type means no overloading unless you change argument with return type.
  • A method can be overloaded in the same class or in a subclass. if class A defines a show(int i) method, the subclass B could define a show(String s) method without overriding the superclass version that takes an int. So two methods with the same name but in different classes can still be considered overloaded, if the subclass inherits one version of the method and then declares another overloaded version in its class definition.

Difference Between Overloading And Overriding

Overloading
Overriding
Overloaded methods let you reuse the same method name in a class, but with different arguments and optionally, a different return type Any time you have a class that inherits a method from a superclass, you have the opportunity to override the method
Overloaded methods must change the argument list. The argument list must be same.
Overloaded methods can change the return type. The return type must be same in jdk 1.4 but in jdk 1.5 it should be co-varient returns.
Overloaded methods can change the access modifier. The access level can't be less restrictive in overridden method.
Overloaded methods can declare new or broader checked exceptions. Can throw any unchecked exception by overriding.
The overridden method can throw any sub type or same type exception of overriding method.
A method can be overloaded in the same class or in a subclass. Without inheritance no overriding.
Can overload final and static methods. You cannot override a method marked final and static.

Overloading With Widening, Wrappers and Var-args

Overloading with widening
/* In this example convert byte into int automatically as int is greater 
than byte */
class Demo{	
public void show(int a){
	System.out.println("inside int...");
}
public void show(long a){
	System.out.println("inside long...");
}
public static void main(String arg[]){
	Demo demo = new Demo();
	byte a=20;
	demo.show(a);
	}
}
Output
inside int...

Overloading With Widening, Wrappers
/* In this example int automatically convert to long */
class Demo{	
	public void show(Integer a){
		System.out.println("inside Integer...");
	}
	public void show(long a){
		System.out.println("inside long...");
	}
	public static void main(String arg[]){
		Demo demo = new Demo();
		int a=20;
		demo.show(a);
	}
}
Output
inside long...

Overloading With Var-args
/* In this example byte automatically convert to int var-args */
class Demo{	
	public void show(long ...a){
		System.out.println("inside long...");
	}
	public void show(int ...a){
		System.out.println("inside int...");
	}

	public static void main(String arg[]){
		Demo demo = new Demo();
		byte a=20;
		demo.show(a);
	}
}
Output
inside int...