Java ProgrammingLearn about Overriding and Overloading Methods in Java

Learn about Overriding and Overloading Methods in Java

java-Overriding-and-Overloading-Methods

In the previous article, we started talking about inheritance in Java; which is a way of reusing class code in other child classes extending the base class. All non-private methods and properties/fields of the parent class become accessible to the child class. Note that Java supports extending from only one class. That is, you cannot inherit from multiple classes, only one base class at a time.

The super() method

But what about the constructor method? Remember that method that is used to execute the code at object instantiation startup? That, too, can be inherited. But doesn’t the child class have a constructor of its own? How can we call the parent’s constructor? That’s where the ‘super’ keyword comes handy. Consider the following example:

[Car.java]

public class Car {
    
    private String _model;
    private String _color;
    private int _cost;
    
    public String getModel(){
        return this._model;
    }
    
    public String getColor(){
        return this._color;
    }
    
    public int getCost(){
        return this._cost;
    }
    
    public Car(String model, String color, int cost){
        this._model = model;
        this._cost = cost;
        this._color = color;
    }
}

[Truck.java]

public class Truck extends Car {
    
    private int _load;
    
    public int getLoad(){
        return this._load;
    }
    
    public Truck(String model, String color, int cost, int load) {
        super(model, color, cost);
        this._load = load;
    }
    
}

[MainClass.java]

public class MainClass {

    public static void main(String[] args) {
       Truck myTruck = new Truck("Toyota","Red",25000,2000);
        System.out.println(myTruck.getColor());
        System.out.println(myTruck.getCost());
        System.out.println(myTruck.getModel());
        System.out.println(myTruck.getLoad());
    }
}

In this example, we create a ‘Car’ class containing three private fields: model, color, and cost. Those fields get assigned to the class upon initialization using the constructor method. We opted to declare our fields as private, and use getter properties to return their values. Then, we created a child class, ‘Truck’, which inherits all the properties and methods of ‘Car’. A truck may need one extra field: load. But since the Car member fields are private, and can only be set using the constructor method, we need to call this constructor method in the Truck’s own constructor method. This is achieved through the use of the super() method. Calling the super() method engages the parent class’s constructor method and does proper field initialization. When you instantiate an object from the Truck class, you can assign values for the inherited fields (model, color, and cost), in addition to the extra field (load) that was introduced in the Truck definition.

Method overriding in child classes

As the name suggests, overriding a method means that you provide your own implementation of a method that has been defined in the parent class. For example, let’s assume that truck brands must be appended by the word “jumbo”. So, to get the name of our truck correctly, it must read “Toyota Jumbo”. Of course, one solution would be to create another method with a different name, perhaps getTruckModel() instead of getModel(), but that would be redundant. In addition, users of your class will become confused: which method do they call when they want to get the truck model? The better solution is to override the getModel() method as follows:

public class Truck extends Car {
    
    private int _load;
    
    public int getLoad(){
        return this._load;
    }
    
    @Override
    public String getModel(){
        return super.getModel() + "-Jumbo";
    }
    
    public Truck(String model, String color, int cost, int load) {
        super(model, color, cost);
        this._load = load;
    }
    
}

Then calling it:

public class MainClass {

    public static void main(String[] args) {
       Truck myTruck = new Truck("Toyota","Red",25000,2000);
        System.out.println(myTruck.getModel());
    }
}

The output of running this code would be “Toyota-Jumbo”. Notice that we place @Override before the method to instruct the compiler that we are overriding a parent method and not overloading it (more on this below). And we cannot call the member field _model directly (since it was declared as private), you had to call the parent method getModel() by prefixing it with the super keyword, after which we concatenated the output to “Jumbo” to return the desired string.

Java Programming Course for Beginner From Scratch

The final keyword

This is used to prevent class members from being overridden by prefixing them with the final keyword. For example, you may not want to override the getColor() method, so in the ‘Car’ class, you can instead modify its definition to be as follows:

final public String getColor(){
        return this._color;
    }

If you try to override this method in a child class, the compiler will raise an error and the code will not run.

Overloading methods in child classes

Overloading means using the same method name but with different parameters. This difference may be in their number or type. For example, let’s say you discovered that a tax would be applied to each truck. Accordingly, the cost should reflect this tax. The original method defined in the ‘Car’ class does not handle taxes, so you will have to implement it in your child class. The difference between overriding and overloading is that, in the first you only changed the implementation, while in the second, you changed both the implementation and parameters passed. You also prefixed the overridden method with the @Override annotation to make it clear that this method is an override of the parent one. You don’t add this annotation in overloaded methods. Consider the following example:

public class Truck extends Car {
    
    private int _load;
    
    public int getLoad(){
        return this._load;
    }
    
    public int getCost(int tax){
        int cost = super.getCost();
        return cost +    (cost * tax/100);
    }
    
    @Override
    public String getModel(){
        return super.getModel() + "-Jumbo";
    }
    
    
    
    public Truck(String model, String color, int cost, int load) {
        super(model, color, cost);
        this._load = load;
    }
    
}
public class MainClass {

    public static void main(String[] args) {
       Truck myTruck = new Truck("Toyota","Red",25000,2000);
        System.out.println(myTruck.getCost(10));
    }
}

In the Truck.java file, we made modifications in the the getCost() method. We created a method of the same name as the one defined in the parent class, but this time we made it accept an integer parameter tax. We use this tax to calculate the cost of a truck after adding it. Now, when you call the getCost() method with or without the tax argument, one of them will print the cost and the other will print the cost + the tax. Note that this differs than calling an overridden method; which lets you only access one version of the method: the overridden one.

Conclusion

In this article, we have added to what we introduced in the previous blogs regarding inheritance in Java. You learned how the constructor method can be called in a child class. Then, you saw how to provide your own implementation of methods both by overriding and overloading them, and you learned the difference between both approaches.

In the next article, we are going to talk about Abstract Classes. An interesting topic to read; so, see you there.

1 COMMENT

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Exclusive content

- Advertisement -

Latest article

21,501FansLike
4,106FollowersFollow
106,000SubscribersSubscribe

More article

- Advertisement -