Principle 3.10.1. EFFECTIVE DESIGN: Inheritance.
The higher up in the class hierarchy that a method is defined, the more widespread its use can be.
Object
’s toString()
method provides our first look at Java’s inheritance mechanism and how it promotes the generality and extensibility of the object-oriented approach. As a subclass of Object
, our OneRowNim
class automatically inherits toString()
and any other public
or protected
methods defined in Object
. We can simply use these methods as is, insofar as they are useful to us. As we saw in this case, the default version of toString()
wasn’t very useful. In that case, we can override the method by defining a method in our class with the exact same method signature. The new version of toString()
can be customized to do exactly what is most appropriate for the subclass.toString()
, at a very high level in the class hierarchy and let the inheritance mechanism spread that task throughout the rest of the hierarchy. Because toString()
is defined in Object
, you can invoke this method for any Java object. Moreover, if you override toString()
in the classes you define, you will be contributing to its usefulness. Two important lessons from this example aretoString()
.
toString()
method can be overridden in any user defined Java class. It is a useful thing to do in any class where the state of an object can be defined briefly.toString()
method is an example of a polymorphic method. The term polymorphism is from the Greek terms poly, which means “many,” and morph, which means “form.” The toString()
method is polymorphic because it has different behavior when invoked on different objects.Student
, as a subclass of Object
and define its toString()
method to return the student ID number. Given this design, then obj.toString()
will return a student ID if obj
is an instance of Student
, but if it is an instance of OneRowNim
, it will return a the description of its state that we defined above. The following code segment illustrates this point:Object obj; // obj can refer to any Object
obj = new Student("12345");// obj refers to a Student
System.out.println(obj.toString()); // Prints "12345"
obj = new OneRowNim(11); // obj refers to a OneRowNim
System.out.println(obj.toString());
// Prints: nSticks = 11, player = 1
obj
is used to refer to a Student
and then to a OneRowNim
instance. This is okay because both classes are subclasses of Object
. When toString()
is invoked on obj
, Java will figure out what subclass of Object
the instance belongs to and invoke the appropriate toString()
method.