Extending a Class

One of the major benefits of object orientation is the ability to extend, or subclass, the behavior of an existing class and continue to use code written for the original class when acting on an instance of the subclass. The original class is known as the superclass. When you extend a class to create a new class, the new extended class inherits fields and methods of the superclass.

If the subclass does not specifically override the behavior of the superclass, the subclass inherits all the behavior of its superclass because it inherits the fields and methods of its superclass. In addition, the subclass can add new fields and methods and so add new behavior.

Consider the Walkman example. The original model had a single jack for one person to listen to the tape. Later models incorporated two jacks so two people could listen to the same tape. In the object-oriented world, the two-jack model extends, or is a subclass of, the basic one-jack model. The two-jack model inherits the characteristics and behavior of the basic model and adds new behavior of its own.

Customers told Sony they wanted to talk to each other while sharing a tape in the two-jack model. Sony enhanced the two-jack model to include two-way communications so people could chat while listening to music. The two-way communications model is a subclass of the two-jack model, inherits all its behavior, and again adds new behavior.

Sony created many other Walkman models. Later models extend the capabilities of the basic modelthey subclass the basic model and inherit features and behavior from it.

Let's look at an example of extending a class. Here we extend our former PointPixel class requires a color in addition to x and y coordinates: class to represent a pixel that might be shown on a screen. The new

class Pixel extends Point 
{
Color color;

public void clear()
{
super.clear();
color = null;
}

}

Pixel extends both the data and behavior of its Point superclass. Pixel extends the data by adding a field named color. Pixel also extends the behavior of PointPoint's clear method. by overriding

Pixel objects can be used by any code designed to work with Point objects. If a method expects a parameter of type Point, you can hand it a Pixel object and it just works. All the Point code can be used by anyone with a Pixel in hand. This feature is known as polymorphisma single object like Pixel can have many ( poly-) forms (-morph) and can be used as both a Pixel object and a Point object.

Pixel's behavior extends Point's behavior. Extended behavior can be entirely new (adding color in this example) or can be a restriction on old behavior that follows all the original requirements. An example of restricted behavior might be PixelScreen object, restricting x and y to the dimensions of the screen. If the original Point class did not forbid restrictions for coordinates, a class with restricted range would not violate the original class's behavior. objects that live inside some kind of

An extended class often overrides the behavior of its superclass by providing new implementations of one or more of the inherited methods. To do this the extended class defines a method with the same signature and return type as a method in the superclass. In the Pixel example, we override clear to obtain the proper behavior that Pixel requires. The clear that Pixel inherited from PointPoint's fields but obviously can't know about the new color field declared in the Pixel subclass. knows only about

Invoking Methods of the Superclass

To make Pixel do the correct "clear" behavior, we provide a new implementation of clear that first invokes its superclass's clear using the super reference. The super reference is a lot like the this reference described previously except that super references things from the superclass, whereas this references things from the current object.

The invocation super.clear() looks to the superclass to execute clear as it would for an object of the superclassnamely, Point. After invoking super.clear() to clear out the Point part of the object, we add new functionality to set color to a reasonable empty value. We choose null, a reference to no object.

What would happen had we not invoked super.clear() in the previous example? Pixel's clearcolor to its null value, but the x and y variables that Pixel inherited from Point would not be set to any "cleared" values. Not clearing all the values of a Pixel object, including its Point parts, is probably a bug. method would set

When you invoke super.method (), the runtime system looks back up the inheritance hierarchy to the first superclass that contains the required method . If Point didn't have a clear method, for example, the runtime system would look at Point's superclass for such a method and invoke that, and so on.

For all other references, invoking a method uses the actual class of the object, not the type of the object reference. Here is an example:

Point point = new Pixel();
point.clear(); // uses Pixel's clear()
In this example, Pixel's version of clear is invoked even though the variable that holds the Pixel is declared as a Point reference. But if we invoke super.clear() inside one of Pixel's methods, that invocation will use the Point class's implementation of the clear method.

The Object Class

Classes that do not explicitly extend any other class implicitly extend the Object class. All objects are polymorphically of class Object, so Object is the general-purpose type for references that can refer to objects of any class:

Object oref = new Pixel();
oref = "Some String";

In this example, oref is correctly assigned references to Pixel and String objects even though those classes have no relationship except that both have Object as a superclass.

Type Casting

The following code fragment seems quite reasonable (if not particularly useful) but results in a compile-time error:

String name = "Petronius";
Object obj = name;
name = obj; // INVALID: won't compile

We declare and initialize a String reference which we then assign to a general-purpose ObjectString back to the String reference. Why doesn't this work? The problem is that while a String is always an Object, an Object is not necessarily a String, and even though you can see that in this case it really is a String, the compiler is not so clever. To help the compiler you have to tell it that the object referred to by obj is actually a String and so can be assigned to name: reference, and then we try to assign the reference to a

name = (String) obj;    // That's Good
Telling the compiler that the type of an expression is really a different type is known as type casting or type conversion. You perform a type cast by prefixing the expression with the new type in parentheses. The compiler doesn't automatically trust you when you do this and so it checks that you are telling the truth. A smart compiler may be able to tell at compile time that you are telling the truth; otherwise, it will insert a run time check to verify that the cast really is allowed. If you lie to the compiler and the run time check fails, the runtime system reports this by throwing a ClassCastException. As the Java programming language is strongly typed there are strict rules concerning assignments between types.

We Are Founder..