Where do I begin? Many object-oriented programming languages (OOPLs) define a default class that all new classes are derived from, unless you specifically indicate a different base. Of course, if you do specify a different base class, your base class must have a base.
Java and C# both implement this default ultimate class behavior (C++ does not). In Java, if you don t specify a base class to a new class, it will default to the Ob ject class as its base (or super) class. C# uses the same name , Object , for its ultimate base class.
Ultimate base classes are used for a number of reasons, but they are typically designed to permit you to work with data in a generic manner. When the designers of the Java and C# languages created their library frameworks, they implemented a design that would be extremely helpful most of the time, but sometimes would just not be applicable . To dive into this statement a bit further, let s look at the Java and C# ultimate base classes, listed in Tables 11-2 and 11-3, respectively.
Method | Access | Description |
---|---|---|
Object Constructor | Public | Initializes an object. |
clone | Protected | Creates and returns a copy of this object. |
equals | Public | Indicates whether some other object is equal to this one. |
finalize | Protected | Called by the garbage collector on an object when it determines there are no more references to the object. |
getClass | Public | Returns the runtime class of the object. |
hashCode | Public | Returns a hash code value for the object. |
notify | Public | Wakes up a single thread that is waiting on this object's monitor. |
notifyAll | Public | Wakes up all threads that are waiting on this object's monitor. |
toString | Public | Returns a string representation of the object. |
Wait | Public | Overloaded versions. Causes the current thread to wait for some event or operation for this object. |
Method | Access | Description |
---|---|---|
Object | Public | This constructor initializes a new instance of the Object class. |
Equals | Public | Determines whether two Object instances are equal. |
GetHashCode | Public | Serves as a hash function for a particular type, suitable for use in hashing algorithms and data structures such as a hash table. |
GetType | Public | Gets the type of the current instance. |
ReferenceEquals | Public | Determines whether the specified Object instances are the same instance. |
ToString | Public | Returns a string that represents the current object. |
Finalize | Protected | Allows an object to attempt to free resources and perform other cleanup operations before it is reclaimed by garbage collection. In C#, finalizers are expressed using destructor syntax. |
MemberwiseClone | Protected | Creates a shallow copy of the current object. |
With the exception of the threading functions in the Java class, you can begin to see some similarities in the design of the classes:
They have a method to compare to objects.
They have a method to clone a new object from an existing object.
They have a method to convert an object to a string.
They have a finalize method to destruct the object.
This certainly goes a long way toward polymorphism. Just image, any object in Java or C# has the ability to format itself into a string or to see whether it is equal to some other object. However, don t forget that someone, somewhere had to write that code. If you create a new class in Java or C# and you want that object to be able to convert a formatted string for itself implicitly, you would want to create a toString method in Java or a ToString method in C#.
So what s the downside to these ultimate base classes? For one, having all objects implement a toString method may simply not be practical. For example, if we had a class for creating and manipulating images, what would toString return for that? For this reason, these ultimate base classes are kept to a bare minimum.
How do these ultimate base classes tie into interfaces? As you ll remember from our discussion at the beginning of this chapter, we explored the similarities between an interface and a base class. We determined that although they are mostly similar, there are a few distinguishing differences. We could have, in theory, designed our examples for this class so that we have an ultimate base class of HTMLSource that provides an abstract GetHTML method and then provide it in each of our derived classes. However, we didn t do this for the following two reasons:
First of all, we simply can t. The ultimate base classes for Java and C# are already defined, and we can t add a GetHTML method to them. The issue is that we can t go and change base classes (or we probably shouldn t, even if we could).
We want to keep ultimate base classes simple and not add methods that are specific to a task or operation, such as dealing with HTML.