Method Overriding and Method overriding in java.
Method Overriding
If subclass (child class) has the same method as declared in the parent class, it is known as method overriding in java.
In other words, If subclass provides the specific implementation of the method that has been provided by one of its parent class, it is known as method overriding.
In this case the method in parent class is called overridden method and the method in child class is called overriding method.
Rules:
- The argument list should be exactly the same as that of the overridden method.
- The return type should be the same or a subtype of the return type declared in the original overridden method in the superclass.
- The access level cannot be more restrictive than the overridden method's access level. For example: If the superclass method is declared public then the overridding method in the sub class cannot be either private or protected.
- Instance methods can be overridden only if they are inherited by the subclass.
- A method declared final cannot be overridden.
- A method declared static cannot be overridden but can be re-declared.
- If a method cannot be inherited, then it cannot be overridden.
- A subclass within the same package as the instance's superclass can override any superclass method that is not declared private or final.
- A subclass in a different package can only override the non-final methods declared public or protected.
- An overriding method can throw any uncheck exceptions, regardless of whether the overridden method throws exceptions or not. However, the overriding method should not throw checked exceptions that are new or broader than the ones declared by the overridden method. The overriding method can throw narrower or fewer exceptions than the overridden method.
If the super-class overridden method does not throws an exception, subclass overriding method can only throws the unchecked exception, throwing checked exception will lead to compile-time error.
/* Java program to demonstrate overriding when superclass method does declare an exception*/ class Parent { void m1() throws RuntimeException { System.out.println("From parent m1()");} } class Child1 extends Parent { @Override // no issue while throwing same exception void m1() throws RuntimeException { System.out.println("From child1 m1()");} } class Child2 extends Parent { @Override // no issue while throwing subclass exception void m1() throws ArithmeticException { System.out.println("From child2 m1()");} } class Child3 extends Parent { @Override // no issue while not throwing any exception void m1() { System.out.println("From child3 m1()");} } class Child4 extends Parent { @Override // compile-time error // issue while throwing parent exception void m1() throws Exception { System.out.println("From child4 m1()");} } Output: error: m1() in Child4 cannot override m1() in Parent void m1() throws Exception ^ overridden method does not throw Exceptio |
- Constructors cannot be overridden.
Method Overriding Example
Lets take a simple example to understand this. We have two classes: A child class Boy and a parent class Human. The Boy class extends Human class. Both the classes have a common method void eat(). Boy class is giving its own implementation to the eat() method or in other words it is overriding the eat() method.
The purpose of Method Overriding is clear here. Child class wants to give its own implementation so that when it calls this method, it prints Boy is eating instead of Human is eating.
class Human{
//Overridden method
public void eat()
{
System.out.println("Human is eating");
}
}
class Boy extends Human{
//Overriding method
public void eat(){
System.out.println("Boy is eating");
}
public static void main( String args[]) {
Boy obj = new Boy();
//This will call the child class version of eat()
obj.eat();
}
}
//Overridden method
public void eat()
{
System.out.println("Human is eating");
}
}
class Boy extends Human{
//Overriding method
public void eat(){
System.out.println("Boy is eating");
}
public static void main( String args[]) {
Boy obj = new Boy();
//This will call the child class version of eat()
obj.eat();
}
}
Output:
Boy is eating
Runtime Polymorphism in Java
Runtime polymorphism or Dynamic Method Dispatch is a process in which a call to an overridden method is resolved at runtime rather than compile-time.
In this process, an overridden method is called through the reference variable of a superclass. The determination of the method to be called is based on the object being referred to by the reference variable.
// A Java program to illustrate Dynamic Method // Dispatch using hierarchical inheritance class A { void m1() { System.out.println("Inside A's m1 method"); } } class B extends A { // overriding m1() void m1() { System.out.println("Inside B's m1 method"); } } class C extends A { // overriding m1() void m1() { System.out.println("Inside C's m1 method"); } } // Driver class class Dispatch { public static void main(String args[]) { // object of type A A a = new A(); // object of type B B b = new B(); // object of type C C c = new C(); // obtain a reference of type A A ref; // ref refers to an A object ref = a; // calling A's version of m1() ref.m1(); // now ref refers to a B object ref = b; // calling B's version of m1() ref.m1(); // now ref refers to a C object ref = c; // calling C's version of m1() ref.m1(); } } |
Output:
Inside A's m1 method
Inside B's m1 method
Inside C's m1 method
Inside B's m1 method
Inside C's m1 method
Explanation :
The above program creates one superclass called A and it’s two subclasses B and C. These subclasses overrides m1( ) method.
Inside the main() method in Dispatch class, initially objects of type A, B, and C are declared.
A a = new A(); // object of type A
B b = new B(); // object of type B
C c = new C(); // object of type C
B b = new B(); // object of type B
C c = new C(); // object of type C
Now a reference of type A, called ref, is also declared, initially it will point to null.
A ref; // obtain a reference of type A
Now we are assigning a reference to each type of object (either A’s or B’s or C’s) to ref, one-by-one, and uses that reference to invoke m1( ). As the output shows, the version of m1( ) executed is determined by the type of object being referred to at the time of the call.
ref = a; // r refers to an A object
ref.m1(); // calling A's version of m1()
ref.m1(); // calling A's version of m1()
ref = b; // now r refers to a B object
ref.m1(); // calling B's version of m1()
ref.m1(); // calling B's version of m1()
ref = c; // now r refers to a C object
ref.m1(); // calling C's version of m1()
ref.m1(); // calling C's version of m1()
Advantages of Dynamic Method Dispatch
Dynamic method dispatch allow Java to support overriding of methods which is central for run-time polymorphism.
It allows a class to specify methods that will be common to all of its derivatives, while allowing subclasses to define the specific implementation of some or all of those methods.
It also allow subclasses to add its specific methods subclasses to define the specific implementation of some.
No comments