13.4 Inheritance and Polymorphism in Java: Using 'super' to Access Superclass Members
Inheritance is one of the fundamental pillars of Object Oriented Programming (OOP), and Java, being a language that adopts this paradigm, offers robust mechanisms to implement it. Inheritance allows a class to inherit characteristics from another class, promoting code reuse and the creation of a class hierarchy. Polymorphism, in turn, is the ability of an object to be referenced in various ways, mainly through its base class or interfaces. Both concepts are essential for understanding and developing efficient Java applications.
When one class inherits from another, the class it inherits is called a subclass, while the class from which it inherits is called a superclass. The subclass inherits fields and methods from the superclass, and can also add new fields and methods or override inherited methods. However, there may be situations where the subclass wants to access the members (fields or methods) of the superclass. This is where using the super
keyword becomes relevant.
Accessing Superclass Members with 'super'
The super
keyword in Java is used within a subclass and serves to directly reference the immediate superclass. It is mainly used in three situations:
- To call the superclass constructor.
- To access a member of the superclass that has been hidden by the subclass (for example, a field with the same name).
- To invoke a superclass method that has been overridden by the subclass.
Calling the Superclass Constructor
When a subclass is instantiated, the superclass constructor is called before the subclass constructor. If the superclass does not have a no-argument constructor (that is, a default constructor), you will need to explicitly call a superclass-specific constructor using super
. This is done in the first line of the subclass constructor:
class Base {
Base(int x) {
System.out.println("Base Constructor with value " + x);
}
}
class Derived extends Base {
Derivative(int x, int y) {
super(x); // Call the Base class constructor
System.out.println("Derivative Constructor with value " + y);
}
}
Accessing Hidden Superclass Members
If a subclass defines a field with the same name as a superclass field, the superclass field is hidden within the subclass. To access the hidden field of the superclass, you can use super
:
class Base {
int number;
}
class Derived extends Base {
int number;
void setNumber(int number) {
this.number = number; // Assigns to subclass field
super.number = number + 10; // Assigns to superclass field
}
}
Invoking Superclass Overridden Methods
When a subclass overrides a superclass method, it can still call the superclass's version of the method using super
. This is useful when you want to extend the functionality of the overridden method, rather than replacing it completely:
class Base {
void show() {
System.out.println("Show from Base");
}
}
class Derived extends Base {
void show() {
super.show(); // Call the show() method of the superclass
System.out.println("Show Derivative");
}
}
Polymorphism and Inheritance
Polymorphism in Java is closely related to inheritance. Through polymorphism, objects of a subclass can be treated as objects of the superclass. This allows methods or reference variables of the superclass to be used to reference objects of any subclass, enabling the execution of subclass-specific overridden methods. The decision about which method to invoke is made at runtime (late binding), which is known as runtime polymorphism or dynamic polymorphism.
For example, consider a superclass called Animal
and subclasses Dog
and Cat
. If both subclasses override a makeSound()
method of the superclass, a method that receives a reference from Animal
can invoke makeSound()
and the sound will be produced depending on whether the referenced object is a Dog
or a Cat
.
class Animal {
void makeSound() {
System.out.println("Generic animal sound");
}
}
class Dog extends Animal {
void makeSound() {
System.out.println("Oof oof");
}
}
class Cat extends Animal {
void makeSound() {
System.out.println("Meow");
}
}
public class TestPolymorphism {
public static void main(String[] args) {Animal myAnimal = new Dog();
myAnimal.makeSound(); // Will produce "Woof woof"
myAnimal = new Cat();
myAnimal.makeSound(); // Will produce "Meow"
}
}
This example illustrates the flexibility and power of polymorphism in Java, where the specific implementation of a method is determined by the actual type of the object and not the type of the reference variable.
Conclusion
Inheritance and polymorphism are key concepts in object-oriented programming and are widely used in Java to create flexible and reusable programs. The super
keyword plays an important role in inheritance, allowing subclasses to interact with members of the superclass in a controlled way. Polymorphism, on the other hand, allows interaction with objects of different classes through a common interface. Understanding these concepts and knowing how to apply them is fundamental for any Java programmer who wants to create robust and maintainable systems.