News & UpdatesProgrammingWeb programming StoreMy Projects
Links
Affiliates

Java Tutorial – 14 – Overriding

A member in a subclass can redefine a member in its superclass. This is most often done to give instance methods new implementations.

Overriding members

In the example below, Rectangle’s getArea method is overridden in Triangle, by redeclaring it there with the same method signature. The signature includes the name, parameters and return type of the method. However, the access level may be changed to allow for more access than the redefined method.

class Rectangle
{
  public int w = 10, h = 10;
  public int getArea() { return w * h; }
}
 
class Triangle extends Rectangle
{
  public int getArea() { return w * h / 2; }
}

Override annotation

In order to show that this override was intentional, the @Override annotation should be placed before the method. This annotation was added in Java 5 to prevent accidental overrides.

class Triangle extends Rectangle
{
  @Override public int getArea() 
  { 
    return w * h / 2;
  }
}

Invoking the getArea method from a Triangle instance will call Triangle’s version of the method.

Triangle o = new Triangle();
 
// calls Triangle's version
o.getArea(); // (50)

If Triangle’s instance is upcast into Rectangle, then Triangle’s version of the method will still get called because Rectangle’s version has been overridden.

Rectangle o = new Triangle();
o.getArea(); // (50) calls Triangle's version

Hiding members

This is only true for instance methods, and not for class methods. If a class method called newArea is added to Rectangle, and redefined in Triangle, then Triangle’s version of the method will only hide Rectangle’s implementation. Because of this the @Override annotation is not used.

class Rectangle
{
  public int w = 10, h = 10;
  public static int newArea(int a, int b) { 
    return a * b; 
  }
}
 
class Triangle extends Rectangle
{
  public static int newArea(int a, int b) { 
    return a * b / 2; 
  }
}

Calling newArea from Triangle’s interface will, as expected, invoke Triangle’s version, but calling the method from Rectangle’s interface will invoke Rectangle’s implementation.

Triangle o = new Triangle();
o.newArea(10,10); // (50) calls Triangle's version
 
Rectangle r = o;
r.newArea(10,10); // (100) calls Rectangle's version

Redefined instance methods will always be overridden in Java and redefined class methods will always be hidden. There is no way to change this behavior, as can be done in for example C++ or C#.

Preventing method inheritance

To prevent an instance method from being overridden in subclasses, it can be declared with the final method modifier.

public final int getArea() { return w * h; }

Bear in mind that the order of the method modifiers is not optional. The compiler will point out when the modifiers appear in the wrong order.

Accessing overridden methods

An overridden method can still be accessed from inside the subclass’s instance methods by using the super keyword. This keyword is a reference to the current instance of the superclass.

@Override public int getArea() 
{ 
  return super.getArea() / 2;     
}

Calling parent constructor

Another place where the super keyword can be used is on the first line of a constructor. There it can perform a method call that invokes the superclass’s constructor.

public Triangle(int a, int b) { super(a,b); }

If the first line of a constructor is not a call to another constructor, the Java compiler will automatically add a call to the superclass’s parameterless constructor. This ensures that all ancestor classes are properly constructed.

public Triangle() { super(); }
Recommended additional reading:
Sams - Teach Yourself Java in 24 Hours