Skip to main content

Section 6.5 Inheritance

Subsection 6.5.1 The Object Class

In Java, the equivalent of __str__ is the toString method. Every object in Java already has a toString method defined for it because every class in Java automatically inherits from the Object class. The Object class provides default implementations for the following methods.
We are not interested in most of the methods on that list, and many Java programmers live happy and productive lives without knowing much about most of the methods on that list. However, to make our output nicer we will implement the toString method for the Fraction class. ListingΒ 6.5.1 shows a simple version of the method.
Listing 6.5.1.
public String toString() {
    return numerator.toString() + "/" + denominator.toString(); // convert to a string
}
The other important class for us to implement from the list of methods inherited from Object is the equals method. In Java, when two objects are compared using the == operator they are tested to see if they are exactly the same object (that is, do the two objects occupy the same exact space in the computer’s memory?). This is also the default behavior of the equals method provided by Object. The equals method allows us to decide if two objects are equal by looking at their instance variables. However it is important to remember that since Java does not have operator overloading if you want to use your equals method you must call it directly. Therefore once you write your own equals method:
Listing 6.5.2.
object1 == object2 // this checks to see if the two objects are the same object in memory
Listing 6.5.3.
object1.equals(object2) // this checks to see if the two objects are equal by looking at their instance variables
ListingΒ 6.5.4 is an equals method for the Fraction class.
Listing 6.5.4.
public boolean equals(Fraction other) { // check if this fraction is equal to another fraction
    Integer num1 = this.numerator * other.getDenominator();
    Integer num2 = this.denominator * other.getNumerator();
    if (num1 == num2)
        return true;
    else
        return false;
}
One important thing to remember about equals is that it only checks to see if two objects are equal – it does not have any notion of less than or greater than. We’ll see more about that shortly.

Subsection 6.5.2 Abstract Classes and Methods

If we want to make our Fraction class behave like Integer, Double, and the other numeric classes in Java then we need to make a couple of additional modifications to the class. The first thing we will do is plug Fraction into the Java class hierarchy at the same place as Integer and its siblings. If you look at the documentation for Integer you will see that Integer’s parent class is Number. Number is an abstract class that specifies several methods that all of its children must implement. In Java an abstract class is more than just a placeholder for common methods. In Java an abstract class has the power to specify certain methods that all of its children must implement. You can trace this power back to the strong typing nature of Java.
ListingΒ 6.5.5 makes the Fraction class a child of Number.
Listing 6.5.5.
public class Fraction extends Number { // fraction class is a child of Number
    ...
}
The keyword extends tells the compiler that the class Fraction extends, or adds new functionality to the Number class. A child class always extends its parent.
The methods we must implement if Fraction is going to be a child of Number are:
This really isn’t much work for us to implement these methods, as all we have to do is some type conversion and some division as shown in ListingΒ 6.5.6.
Listing 6.5.6.
public double doubleValue() { // convert to a double
    return numerator.doubleValue() / denominator.doubleValue();
}
public float floatValue() { // convert to a float
    return numerator.floatValue() / denominator.floatValue();
}
public int intValue() {  // convert to an int
    return numerator.intValue() / denominator.intValue();
}
public long longValue() { // convert to a long
    return numerator.longValue() / denominator.longValue();
}
By having the Fraction class extend the Number class we can now pass a Fraction to any Java method that specifies it can receive a Number as one of its parameters. For example many Java user interface methods accept any object that is a subclass of Number as a parameter. In Java the class hierarchy and the β€œis-a” relationships are very important. Whereas in Python you can pass any kind of object as a parameter to any method or function, the strong typing of Java makes sure that you only pass an object as a parameter that is of the type specified in the method signature, or one of the children of the type specified. When you see a parameter of type Number it’s important to remember that an Integer is-a Number and a Double is-a Number and a Fraction is-a Number, because these classes are children of Number.
However, and this is a big however, it is important to remember that if you specify Number as the type of a particular parameter then the Java compiler will only let you use the methods of a Number: longValue, intValue, floatValue, and doubleValue.
Suppose you try to define a method as ListingΒ 6.5.7.
Listing 6.5.7.
public void test(Number a, Number b) {
    a.add(b); // this is a bad idea
}
The Java compiler would give an error because add is not a defined method of the Number class. You will still get this error even if all your code that calls this test method passes two Fractions as parameters (remember that Fraction does implement add).

Checkpoint 6.5.8.

Construct the toString method for the Fraction class so that printing a fraction shows it in the form numerator/denominator. Drag the blocks into the correct order on the right.
You have attempted of activities on this page.