Open In App

Java – Covariant Method Overriding with Examples

Last Updated : 05 Feb, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

The covariant method overriding approach, implemented in Java 5, helps to remove the client-side typecasting by enabling you to return a subtype of the overridden method’s actual return type.

Covariant Method overriding means that when overriding a method in the child class, the return type may vary. Before java 5 it was not allowed to override any function if the return type is changed in the child class. But now it is possible only return type is subtype class.

Overriding the Covariant approach provides a way for you to return the subtype of the overridden method’s actual return class. It helps to eliminate the burden of typecasting from the programmer. This method is often used when an object is returned by the overriding method.

Let’s have an example to understand it. The function clone() returns the object of the class Object. But since each class is the child of the object class, we will return the object of our own class. Suppose the overriding concept of the Covariant mechanism has not yet been implemented. Then we still need to cast the object. If the cast is not used then “Object cannot be converted to Student” error occurs.

Example 1:

Java




// Covariant Method Overriding of Java
import java.util.ArrayList;
// Student class
class Student implements Cloneable {
    int rollNo;
    String className;
    String name;
  
    // Getters and setters
    public int getRollNo() { return rollNo; }
    public void setRollNo(int rollNo)
    {
        this.rollNo = rollNo;
    }
    public String getClassName() { return className; }
    public void setClassName(String className)
    {
        this.className = className;
    }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
  
    // Class constructor
    public Student(int rollNo, String className,
                   String name)
    {
        this.rollNo = rollNo;
        this.className = className;
        this.name = name;
    }
  
    // Print method
    public void printData()
    {
        System.out.println("Name : " + name
                           + ", RollNo: " + rollNo
                           + ", Class Name : " + className);
    }
  
    // Override the clone method
    @Override
    public Object clone() throws CloneNotSupportedException
    {
        return super.clone();
    }
}
  
// Driver code
public class GFG {
    public static void main(String arg[])
        throws CloneNotSupportedException
    {
        // new student object created
        Student student1 = new Student(1, "MCA", "Kapil");
        student1.printData();
  
        // Student object created using clone method
        // assuming type casting is required
        Student student2 = (Student)student1.clone();
        student2.setName("Sachin");
        student2.setRollNo(2);
        student2.printData();
    }
}


Output

Name : Kapil, RollNo: 1, Class Name : MCA
Name : Sachin, RollNo: 2, Class Name : MCA

In the above example when we are using the clone() method, it returns the object of Object class, and then we typecast it into Student class.

Student student2 = (Student) student1.clone();

Suppose we use the clone method in the program 10 times, so we need to type it each time. We should override the Covariant approach to solve these types of issues. We will return the object of the student class rather than the object class by using the concept of Covariant.

Let’s see how we’re going to use it.

Example 2:

Java




// Covariant Method Overriding of Java
import java.util.ArrayList;
// Student class
class Student implements Cloneable {
    int rollNo;
    String className;
    String name;
  
    // Getters and setters
    public int getRollNo() { return rollNo; }
    public void setRollNo(int rollNo)
    {
        this.rollNo = rollNo;
    }
    public String getClassName() { return className; }
    public void setClassName(String className)
    {
        this.className = className;
    }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
  
    // Class constructor
    public Student(int rollNo, String className,
                   String name)
    {
        this.rollNo = rollNo;
        this.className = className;
        this.name = name;
    }
  
    // Print method
    public void printData()
    {
        System.out.println("Name : " + name
                           + ", RollNo: " + rollNo
                           + ", Class Name : " + className);
    }
  
    // Override the clone method
    @Override
    public Student clone() throws CloneNotSupportedException
    {
        return (Student) super.clone();
    }
}
  
// Driver code
public class GFG {
    public static void main(String arg[])
        throws CloneNotSupportedException
    {
        // new student object created
        Student student1 = new Student(1, "MCA", "Kapil");
        student1.printData();
  
        // Student object created using clone method
        Student student2 = student1.clone();
        student2.setName("Sachin");
        student2.setRollNo(2);
        student2.printData();
    }
}


Output

Name : Kapil, RollNo: 1, Class Name : MCA
Name : Sachin, RollNo: 2, Class Name : MCA

We can see above, since we’re returning a Student class object instead of an Object class, we don’t need to type the object returned from the clone() method into Student.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads