The JavaTM Tutorial
Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Trail: Learning the Java Language
Lesson: Classes and Inheritance

Overriding and Hiding Methods

An instance method in a subclass with the same signature and return type as an instance method in the superclass overrides the superclass's method. (Remember that a method's signature is its name and the number and the type of its arguments.) You can also override a method with the same signature that returns a subclass of the object returned by the original method. This facility (introduced in 5.0) is called covariant return type and you can see an example in Annotations (in the Learning the Java Language trail).

The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. For example, the Object class contains an instance method called toString that returns a string representation of an instance of that type. Every class inherits this method. The implementation in Object is not very useful for subclasses; thus, we recommend overriding this method to provide better information for your classes. It's particularly useful for debugging. Here's an example of overriding toString:

public class MyClass {
    private int anInt = 4;
    //Overrides toString in Object class.
    public String toString() {
        return "Instance of MyClass. anInt = " + anInt;
    }
}
The overriding method has the same name, number and type of arguments, and return value as the method it overrides. (In fact the return type of a subclass can be a subclass of the return type of its superclass. See the The clone Method (in the Learning the Java Language trail) section for an example.) The overriding method can have a different throws clause as long as it doesn't specify any types not specified by the throws clause in the overridden method. Also, the access specifier for the overriding method can allow more but not less access than the overridden method. For example, a protected method in the superclass can be made public but not private.

A subclass cannot override methods that are declared final in the superclass (by definition, final methods cannot be overridden). The Writing Final Classes and Methods (in the Learning the Java Language trail) section discusses final methods in detail.

A subclass must override methods that are declared abstract in the superclass, or the subclass itself must be abstract. The Writing Abstract Classes and Methods (in the Learning the Java Language trail) section discusses abstract classes and methods in detail. Recall from Naming a Method (in the Learning the Java Language trail) that the Java programming language allows you to overload methods by changing the number or the type of arguments to the method. You can also overload methods in a superclass. Here's an example of overloading the toString method:

public class MyClass {
    private int anInt = 4;
    //Overrides toString in Object class.
    public String toString() {
        return "Instance of MyClass. anInt = " + anInt;
    }
	//Overloads toString method name to provide 
	//additional functionality.
    public String toString(String prefix) {
        return prefix + ": " + toString();
    }
}
As illustrated by the preceding example, you might overload a superclass method to provide additional functionality. When writing a method that has the same name as a method in a superclass, double check the return values and the argument lists to make sure that you are overloading or overriding as you intended.

When overriding a method, you might want to use the @Override annotation which instructs the compiler that you intend to override a method in the superclass. If, for some reason, the compiler detects that the method does not exist in one of the superclasses, it will generate an error. For more information on @Override, see Annotations (in the Learning the Java Language trail)

If a subclass defines a class method with the same signature as a class method in the superclass, the method in the subclass hides the one in the superclass. The distinction between hiding and overriding has important implications. Let's look at an example to see why. This example contains two classes. The first is Animal, which contains one instance method and one class method:

public class Animal {
    public static void hide() {
        System.out.format("The hide method in Animal.%n");
    }
    public void override() {
        System.out.format("The override method in Animal.%n");
    }
}
The second class, a subclass of Animal, is called Cat:
public class Cat extends Animal {
    public static void hide() {
        System.out.format("The hide method in Cat.%n");
    }
    public void override() {
        System.out.format("The override method in Cat.%n");
    }

    public static void main(String[] args) {
        Cat myCat = new Cat();
        Animal myAnimal = myCat;
        //myAnimal.hide();   //BAD STYLE
        Animal.hide();       //Better!
        myAnimal.override();
    }
}
The Cat class overrides the instance method in Animal called override and hides the class method in Animal called hide. The main method in this class creates an instance of Cat and calls the hide on the class and override on the instance.

It is considered bad style to call static methods on instances because hiding can be confusing. So it is better to use the class, for example Animal.hide or Cat.hide. The output from this program is as follows:

The hide method in Animal.
The override method in Cat.
The version of the hidden method that gets invoked is the one in the superclass, and the version of the overridden method that gets invoked is the one in the subclass. For class methods, the runtime system invokes the method defined in the compile-time type of the reference on which the method is called. In the example, the compile-time type of myAnimal is Animal. Thus, the runtime system invokes the hide method defined in Animal. For instance methods, the runtime system invokes the method defined in the runtime type of the reference on which the method is called. In the example, the runtime type of myAnimal is Cat. Thus, the runtime system invokes the override method defined in Cat.

An instance method cannot override a static method, and a static method cannot hide an instance method. The following table summarizes what happens when you define a method with the same signature as a method in a superclass.

Defining a Method with the Same Signature as a Superclass's Method
  Superclass Instance Method Superclass Static Method
Instance Method Overrides (return type must be a subtype of the return type of the superclass's method) Generates a compile-time error
Static Method Generates a compile-time error Hides

Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail > Start of Lesson Search
Feedback Form

Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.