8️⃣

12.8 Overriding

You can override a superclass’s methods in a subclass. Overriding means that you take the exact same method (same name, return type, parameter list; in other words, the same method signature) and you change the implementation in the subclass.
 
All classes implicitly inherit from a class called Object, which means that they also inherit Object’s methods and fields. When you write code for a class, it’s usually a good idea to override some of the methods in Object, such as the toString() and equals() method.

toString()

The toString() method is useful for displaying an object in a way that is readable for humans. By default (in the Object class), toString() is implemented such that if you print the object, it will print the name of the class and the location in memory that the object is stored, in hexadecimal.
 
Obviously, we don’t want that to happen, so to fix that we can override the toString() method in the class that we’re writing. For example, say I have a class called Point that has 2 fields x and y, which are the coordinates. It would be nice if I could display the Point object in String form as "(x, y)". I can do that by writing the code below (pay attention to highlighted portion):
class Point { public double x; public double y; public Point() { x = 0; y = 0; } public Point(double x, double y) { this.x = x; this.y = y; } @Override public String toString() { return String.format("(%f, %f)", x, y); } }
View this code on GitHub
 
Did you notice the @Override? This is called an override annotation, which you should put before the method signature of a method that overrides another method. It helps prevent mistakes when overriding. For example, if you put an override annotation above a method that doesn’t actually override anything, it will give you a compile error.
 
Did you notice String.format()? It’s a static method in the String class that allows you to do string formatting, which is where the %f comes in. Basically, %f is a placeholder for a floating point number (or double). The values of x and y replace wherever the %f is. Here’s an article about string formatting: https://www.javatpoint.com/java-string-format. If string formatting confuses you, you can always concatenate strings with variables normally.
 

Overloading vs. Overriding

Now that we know what overriding is, what’s the difference between overriding and overloading?
Here’s how you can keep the terms straight:

Overriding

  • Overriding means you are changing the implementation for the exact same method (same method signature)
  • Overriding a method can only happen in different classes

Overloading

  • Overloading means you are creating a different method with the same method name, but different parameter list
  • Overloading a method can happen in the same class or in different classes
 
For example, below we are overloading the getDistance() method in the Point class. One of them has 2 parameters of type double, while the other has 1 parameter of type Point.
 
Here’s an example of overloading a method.
/** * Returns the distance between this Point * and the given point with coordinates (x, y) * @param x x coordinate of the other point * @param y y coordinate of the other point * @return the distance between this Point * and the given point with coordinates (x, y) */ public double getDistance(double x, double y) { return Math.sqrt(Math.pow(this.x - x, 2) + Math.pow(this.y - y, 2)); } /** * Returns the distance between this Point * and the given Point * @param pt the other Point * @return the distance between this Point * and the given Point */ public double getDistance(Point pt) { return getDistance(pt.x, pt.y); }
View this code on GitHub
 
Notice that both methods are named getDistance. In other words, they do the same thing. However, they have different parameter lists: one of them takes 2 doubles, while the other takes a single Point object. This allows developers to use different methods depending on what their needs are. Basically, it’s more convenient.
 
Also notice how we can use the other version of the method to help us write code. The second getDistance method takes advantage of the fact that every Point has an x and y coordinate and calls the first getDistance method on that Point object’s x and y fields.

Putting it All Together

Here’s a driver program to test the Point class. You should try running it on your own computer to make sure it works as intended.
public class TestPoint { public static void main(String[] args) { Point pt1 = new Point(5, 0); Point pt2 = new Point(1.4, -15); System.out.println("Point 1: " + pt1); // prints "Point 1: (5, 0)" System.out.println("Point 2: " + pt2); // prints "Point 2: (1.4, -15)" // the following prints the same distance, demonstrating // overloading the getDistance() method System.out.println(pt1.getDistance(pt2)); System.out.println(pt1.getDistance(1.4, -15)); } }
View this code on GitHub

Practice

Time and Date

Create 2 classes: MyTime and MyDate.
 
 
The toString() method for the MyTime class should display the object like so:
hours:minutes:seconds
 
For example, 5 hours, 35 minutes, and 45 seconds would be: 5:35:45
 
The toString() method for the MyDate class should display the object like so:
MM/DD/YYYY
 
For example, May 25, 2020 would be:
5/25/2020
 
Create a driver program called TimeAndDate, which creates a MyTime and MyDate object and prints out the current time and date.
 
⚖️
Copyright © 2021 Code 4 Tomorrow. All rights reserved. The code in this course is licensed under the MIT License. If you would like to use content from any of our courses, you must obtain our explicit written permission and provide credit. Please contact classes@code4tomorrow.org for inquiries.