© Mikael Olsson 2018
Mikael OlssonJava Quick Syntax Referencehttps://doi.org/10.1007/978-1-4842-3441-9_13

13. Overriding

Mikael Olsson1 
(1)
Hammarland, Länsi-Suomi, Finland
 

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 following example, 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 method being overridden:

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

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();
o.getArea(); // (50) calls Triangle's version

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—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 isn’t 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’s no way to change this behavior, as can be done in C++ or C#, for example.

Preventing method inheritance

To prevent an instance method from being overridden in subclasses, you can declare it with the final modifier:

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

Bear in mind that the order of the method modifiers isn’t 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 using the super keyword. This keyword is a reference to the current instance of the superclass:

class Triangle extends Rectangle
{
  @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 isn’t a call to another constructor, the Java compiler will automatically add a call to the superclass’s parameterless constructor. That ensures that all ancestor classes are properly constructed:

public Triangle() { super(); }
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.17.18