Method overriding allows a subclass to have a method with the same name as a method in a base class. Method overriding is a very powerful Java feature and one of the ways in which Java achieves polymorphism. In this article, we will be exploring method overriding.

  1. What is a Method Overriding
  2. Super Keyword
  3. Runtime Polymorphism
  4. Method Overriding Rules
  5. Final Keyword

Method Overriding in Java

What is Method Overriding

Method overriding is related to inheritance. When a sub-class has a method with the same name as a method in a base class, then the subclass method is said to override the base class method. The method in the sub-class is known as the overriding method and the method in the base class is known as the overridden method. Method overriding allows the sub-class method to provide its own implementation for the base class method.

Code Sample


public class Animal {

  public void talk() {
    System.out.println("I’m an animal");
  }
}

public class Cat extends Animal {

  public void talk() {
    System.out.println("I’m a cat ");
  }
}

public class AnimalDemo {

  public static void main(String[] args) {
    Animal animal = new Animal();
    animal.talk();

    Cat cat = new Cat();
    cat.talk();
   }
}

  • Line 1 specifies a class called Animal. It has a method called talk
  • Line 8 specifies a class called Cat. It also has a method called talk
  • Since both classes have a method called talk, the talk method in the Cat class is said to override the talk method in the Animal class
  • Line 15 specifies an AnimalDemo class
  • Line 18 creates an Animal object and Line 19 invokes the talk method on the Animal object
  • Similarly, Line 21 creates a cat object and Line 22 invokes the talk method on the cat object.

Output

I’m an animal
I’m a cat

Super Keyword

Sometimes, although an overriding method may provide a different implementation for a base class method, it may still need to execute the code in the overridden method. The super keyword is useful in such scenarios.

Sample Code


public class Person {

  protected String name;

  public void printDetails() {
    System.out.println("Name:"+name);
  }
}

public class Employee extends Person {

  private String designation;
  private String department;

  public void printDetails() {
    System.out.println("designation:"+designation);
    System.out.println("department:"+department);
    super.printDetails();
  }

  public static void main(String arg[]) {
    Employee employee = new Employee();
    employee.name = "John Doe";
    employee.designation = "Manager";
    employee.department="HR";
    employee.printDetails();
  }
}

  • Line 1 defines a Person class. It has a name instance field. It also has a printDetails method that simply prints the name
  • Line 10 defines an Employee class that is a subclass of Person. It has fields corresponding to designation and department.
  • Employee class also has a printDetails method. So the printDetails method in the Employee class overrides the printDetails method in the Person class.
  • The Employee.printDetails method prints the designation and department instance fields. In addition, it invokes super.printDetails(). This causes the printDetails method in the Person class to be invoked.

Output

designation:Manager
department:HR
Name:John Doe

Runtime polymorphism

The main advantage of method overriding is that it is the mechanism by which Java achieves runtime polymorphism. When an overridden method is invoked, the version of the method that actually gets invoked is determined at run-time. This is known as dynamic method dispatch. Dynamic method dispatch helps to achieve runtime polymorphism.

Code Sample

Suppose the AnimalDemo class above is re-written as follows:

public class AnimalDemo {

  public static void main(String[] args) {
    Animal animal = new Cat();
    animal.talk();
  }
}

  • Line 4 declares a variable of type Animal but assigns it an object of type Cat. This is allowed, you can assign a subclass object to a variable of the base class type
  • Line 5 invokes the talk method on the animal variable

Output

I’m a cat

So, the call at Line 5 results in invoking the talk method in the Cat class. So it is the type of the object assigned to the base class variable that determines the version of the overridden method that will get invoked.

Now suppose we have another class as follows:


public class Dog extends Animal {

  public void talk() {
    System.out.println("I’m a dog");
  }
}

This code defines a class called Dog that extends the Animal class and overrides the talk method. Now, let us modify the AnimalDemo class again:


public class AnimalDemo {

  public static void main(String[] args) {
    Animal animal = new Cat();
    animal.talk();

    animal = new Dog();
    animal.talk();
  }
}

  • Line 4 declares a variable of type Animal and assigns it an object of type Cat. Line 5 invokes the talk method on the animal variable
  • Line 7 assigns an object of type Dog to the animal variable and Line 8 invokes the talk method on the animal variable
  • Since the version of the method to be invoked depends on the type of object assigned to the superclass variable, Line 5 results in the talk method from Cat class being invoked while Line 8 results in the talk method from the Dog class being invoked.

Output

I’m a cat
I’m a dog

Method overriding rules

There are some rules that need to be followed in method overriding. These are as follows:

  • The parameter list in the overriding and overridden method must be exactly the same. So, for example, if the base class method accepts two parameters of type int, the sub-class method should also accept two parameters of type int
  • The return type of the overriding method must be the same or a subtype of the return type of the overridden method. So, for example, if a base class method returns a Collection, the sub-class method can either return a Collection or any sub-type of Collection
  • The access level of the overriding method should be the same or less restrictive than the overridden method. So, if the base class method is declared as public, then the subclass method cannot be private, protected, or have a default access.
  • The overriding method cannot throw checked exceptions that are new or broader than the overridden method. So, if the base class method does not throw any checked exceptions, the sub-class method also cannot throw any exceptions. If the base class method throws a checked exception like SQLException, then the subclass method can only throw an exception which is a sub-class of SQLException
  • Constructors cannot be overridden.

Final Keyword

Sometimes, you may wish to prevent a method from being overridden. In such a case, the final keyword can be used with the base class method. This prevents a method from being overridden.

Code Sample


public class Vehicle {

  final void move() {
    System.out.println("Moving");
  }
}

public class Car extends Vehicle{
  void move() {
    System.out.println("Moving");
  }
}

  • Line 1 specifies a class called Vehicle
  • Line 3 specifies a move method. It has the final keyword specified in the method declaration. This indicates that the move method cannot be overridden.
  • Line 8 specifies a class called Car with a method called move. However, this causes a compilation error since the move method in the Vehicle class is final.

Conclusion

So, in this article, we understood what method overriding is and how it works. We saw how method overriding helps to achieve runtime polymorphism. We also saw what rules need to be followed for method overriding. Finally, we saw how to prevent method overriding by using the final keyword.