2 min read

Instance method overriding in Java

Instance method overriding in Java
Photo by Sarah Kilian / Unsplash

Overriding in Java occurs when an instance method of a class has the same signature (name, number and types of parameters), and return type as an instance method in the super class.

Overriding is an important concept, because it allows a subclass to inherit behaviour of its super class that is "close enough", and then modify it as needed.

public class BobCat {
  public void findDen() {}
}

class BobCatKitten extends BobCat {
  public void findDen() {}
  public void findDen(boolean b){}
  public int findden() throws Exception{return 0;}
}

Which methods from BobCatKitten override the one in BobCat in the snippet above? Line 6 overrides findDen in BobCat.  Line 7 overloads findDen. While line 8 is altogether a different method.

Access specifier in instance method overriding

In the Rectangle class in Fig 1, we can see that the overriden instance method; area uses a less restrictive access specifier. It is protected in the superclass, but public in the subclass.

Fig1: overriding an instance method using more restrictive access specifier in subclass

A compile-time error is thrown when a more restrictive access specifier is used in the subclass, as is shown in Fig 2.

Fig 2: compile error when attempting to use a less restritive access specifier in the subclass, during overriding

Covariant Return type

A subclass that overrides an instance method in a superclass can have a return type that is either the same or a subclass of the superclass return type. This subclass of the superclass return type is called a covariant return type.

In the code snippet below, notice that in the Shape class, line 25 declares an abstract method: move, which returns a Point class. Line 36 of the Rectangle class implements this move class, but returns a subclass of Point, Position. It returns a covariant return type.

class Point{
  protected int x;
  protected int y;
  Point() {}
  Point(int x, int y) {
    x = x;
    y = y;
  }
}

class Position extends Point {
  protected int z;
  Position() {

  }
  Position(int x, int y, int z) {
    super (x, y);
    z = z;
  }
}

abstract class Shape {
  protected Point point;
  protected abstract double area();
  protected abstract Point move(int newX, int newY, int newZ);
}

public class Rectangle extends Shape {
  private int length = 0;
  private int breadth = 0;

  public double area() {
    return length * breadth;
  }

  public Position move(int newX, int newY, int newZ) {
    return new Position();
  }
}


Points to remember about instance method overriding

  1. Overriding only happens for instance methods, not static methods (static methods use method hiding instead).
  2. For overriding to happen, the instance method of the subclass has to have the same signature (name, number and types of paramters) and return type as an instance method in the super class.
  3. In overriding, the return type of a subclass can also be a subtype of the return type in the overriden method. This is called a covariant return type
  4. Access modifier in the overriden method can only be the same or more restrictive, never less restrictive. For example, a protected method in the superclass can be made public, but not private.