A subclass can override (replace) an inherited method so that the subclass's version of the method is called instead.
An overriding method must specify the same name, parameter list, and return type as the method being overridden.
Here is an example.
class Vehicle {
private String make;
private String model;
private int year;
Vehicle(String make, String model, int year) {
this.make = make;
this.model = model;
this.year = year;
}
// getters and setters
void print() {
System.out.println("Make: " + make + ", Model: " + model + ", Year: " + year);
}
}
class Truck extends Vehicle {
private double tonnage;
Truck(String make, String model, int year, double tonnage) {
super(make, model, year);
this.tonnage = tonnage;
}
double getTonnage() {
return tonnage;
}
void print() {
super.print();
System.out.println("Tonnage: " + tonnage);
}
}
Truck
's print()
method has the
same name, return type, and parameter list as Vehicle
's print()
method.
Note that Truck
's print()
method first calls Vehicle
's print()
method by prefixing super
to
the method name. It often makes sense to execute the superclass logic first and then execute the
subclass logic.
In order to call a superclass method from the overriding subclass method, prefix the method's name
with the reserved word super
and the member access operator.
Otherwise you will end up recursively calling the subclass's overriding method.
void print() {
super.print();
System.out.println("Tonnage: " + tonnage);
}
In some cases a subclass will mask non-private superclass fields by declaring same-named fields. You can use super and the member access operator to access the non-private superclass fields.
class Vehicle {
String make;
// ...
}
class Truck extends Vehicle {
String make;
// ...
void print() {
super.make;
this.make;
// ...
}
}
@Override
It is a good practice to annotate the overriding methods with the annotation @Override
@Override
void print() {
super.print();
System.out.println("Tonnage: " + tonnage);
}
Advantages:
this
vs super
this
refers to this class.super
refers to the parent class.class Animal {
public void whoAreYou() {
System.out.println("I am an animal");
}
}
class Fish extends Animal {
public void whoAreYou() {
System.out.println("I am a Fish");
}
public void whoAreYouReally() {
super.whoAreYou();
this.whoAreYou();
}
}
public class ThisSuper {
public static void main(String[] args) {
Animal a = new Animal();
a.whoAreYou();
System.out.println("---");
Fish f = new Fish();
f.whoAreYou();
System.out.println("---");
f.whoAreYouReally();
}
}
I am an animal
---
I am a Fish
---
I am an animal
I am a Fish
Occasionally you might need to declare a method that should not be overridden (for security reasons, for instance).
You can use the final
keyword for this purpose.
final String getMake()
The compiler will then report an error if anyone attempts to override this method in a subclass.
Complete the classes below such that class Car
overrides setLicensePlate(String)
defined in Vehicle
.
public class Car extends Vehicle {
int numberOfSeats = 4;
}
public class Vehicle {
private String licensePlate;
public String getLicensePlate() {
return licensePlate;
}
public void setLicensePlate (String licensePlate) {
this.licensePlate = licensePlate;
}
}
You can find the solution to this exercise here.
Using the Bicycle
class below,
write a MountainBike
class that specializes it.
public class Bicycle {
int speed = 0;
int gear = 1;
void changeGear(int newValue) {
gear = newValue;
}
void speedUp(int increment) {
speed = speed + increment;
}
void applyBrakes(int decrement) {
speed = speed - decrement;
}
@Override
public String toString() {
return "speed:" + speed + ", gear:" + gear;
}
}
We have the following requirements for the specialized class.
int seatHeight
toString()
method reuses Bicycle::toString()
but adds the seatHeight
value.Now write a Runner
class that creates objects and calls methods of
both classes.
You can find the solution to this exercise here.
Write InverseString
, a class that implements the java.lang.CharSequence
interface.
You will have to implement the following.
char charAt(int index)
: Returns the char value at the specified
index.int length()
: Returns the length of this character sequence.
CharSequence subSequence(int start, int end)
: Returns a
CharSequence that is a subsequence of this sequence.String toString()
: Returns a string containing the characters
in this sequence in the same order as this sequence.The special characteristic of InverseString
is that it inverts the
CharSequence
given as input in its constructor.
Then, write a small main()
method to test your class; make sure to
call all four methods.
You can find the solution to this exercise here.