Java Programming   Java Programming
 |Sofia Home | Content Gallery |
Home
Syllabus
Schedule
Lessons
Assignments
Resources

Lesson 10.2 Subclasses

Creating a Subclass

Lesson 9, "Composite Objects", taught you about the HASA relationship. In this lesson you'll learn how to create a subclass from an existing component and how to use the inherited methods that the subclass receives from its superclass.

As you've already learned, we can say that a Label object has-a background color property, for instance. In a HASA relationship one component is composed of other parts. A Bicycle class thus may contain two objects of the Wheel class.

Inheritance is a different kind of relationship. An inheritance relationship is called an ISA relationship [iz-uh, not eye-ess-ay]. The ISA relationship describes a relationship strictly between classes, where the members of one class form a subset of another class.

A hierarchy of classes and objects

Here's an example from your text. Suppose that all of the animals in the world could be lumped together into the class of JavaDrinkingAnimals. If we took all of the JavaDrinkingAnimals, and divided them into different groups, we might find that some were Mammals, some were Insects, etc. Each of these groups would compose a subset of the entire class of JavaDrinkingAnimals. Such a subset [Mammal, Insect, Amphibian] is called a subclass, and, as you might expect, the superset [JavaDrinkingAnimal] is called the superclass.

This relationship is called an ISA relationship because if an object belongs to a subclass, [Brenda and Jumbo in the Elephant class, for instance], that object is simultaneously a member of each of the ancestor classes also. We can say that Jumbo is an Elephant, but, by virtue of being an Elephant, he is, simultaneously, a Mammal and a JavaDrinkingAnimal as well.

What's It Mean?

Let's take a look at what the ISA relationship means, and then we'll come back and put it to work.
Back to Top

Inherited Methods and Fields

Each subclass object contains all attributes and methods of its superclass. Some of those methods may not be accessible to the subclass object, because they were declared private in the superclass, but they are there nonetheless.

Those methods [and fields] that are not declared private in the superclass are called inherited methods [and fields]. An object may use its inherited methods and fields without any further qualification, exactly as if they were defined inside the object's own class.

Specialization and Extension

Normally, however, a subclass extends an existing class by adding additional fields or methods. That is because logically, a subclass represents specialization. The Elephant class represents a specialized form of Mammal, and the Mammal class represents a specialized form of JavaDrinkingAnimal.
Back to Top

Substitutablility

Because every Elephant is also a Mammal, any time a Mammal is required, you can supply an Elephant to meet the need. For instance, this is permissible:

Mammal fred = new Elephant();

as is this:

Elephant jumbo = new Elephant();
public void feed(Mammal m)
{
// General Mammal feeder
}
feed(jumbo);

You can pass an Elephant to any method that requires a Mammal, because every Elephant is also a Mammal. This is called the principle of substitutability. You can always substitute a subclass object when a superclass object is needed.

The reverse is not true, however, you cannot pass a Mammal object to a method that requires an Elephant. All Elephants are Mammals, but not all Mammals are Elephants. This, therefore, is illegal:

Mammal tom = new Mammal();
public void feed(Elephant e)
{
// Specialized Elephant feeder
}
feed(tom); // OOPS. not an Elephant

Single Inheritance

There is one last thing you should note about Java's inheritance model. Each subclass can have only one immediate superclass. This is called single inheritance. Because of this, you cannot create a subclass that combines the characteristics of two classes using inheritance. Such a facility is called Multiple Inheritance.

Java has other facilities for achieving this goal, however. You can use composition, or another Java feature called the interface.

Back to Top

Subclassing and Inherited Methods

For the rest of this lesson, we'll explore Java's inheritance facilities using a concrete example, the MyLabel class and a few of its decendents. As in the last unit, you'll learn more if you break out the keyboard and compiler, and type along.

Creating a Subclass

Creating a subclass is easy. You've been doing it since you wrote your first applet. For this class, however, we want to create a new class that extends one of the built-in component classes, the Label.

"I Can't Get X to Work!!!"
Before we start working on the MyLabel class, you should be prepared for the possiblity that not everything may work exactly the way you [or I] think it should.

The Java AWT classes [Button, Label, etc] are among the least "portable" between different platforms, because they are tightly bound to the underlying native GUI toolkit. Thus, you may find that you can change the color of a Label on a Windows and a Mac, but on the Mac, you can't change the color of a Button, perhaps.

You may also find that sizing and positioning of different components varies as you run your programs under different Java Virtual Machines [Navigator vs IE, for instance] even on the same platform.

Don't let any of these things throw you, and don't get bogged down trying to solve them. The problem is not on your end. Simply pick up your keyboard, and move on.

Back to Top

Using Extends

To create a new subclass you use the extends keyword, just as you've done in all your applets. This time, however, instead of extending the Applet class, you're going to extend Label.

Here are the steps to follow:

  1. Create a new file with your text editor called MyLabel.java
  2. Enter the source code that appears below.
  3. Compile using javac
MyLabel.java
import java.awt.*;

public class MyLabel extends Label
{
/* New attributes and
methods added here */
}

Notice that the MyLabel class does not need to import the java.applet package, but that it does need to import java.awt, because that is where the java.awt.Label class is defined. One interesting thing is that we don't need access to the source code to extend the Label [or any other class]; all that's needed is the compiled object code.

The new MyLabel class is fairly Spartan; it includes absolutely no new methods at all. Even without any new code, however, the MyLabel class is pretty impressive for the talents it has inherited from its ancestors.

Let's take a look at those talents in the next section.

Back to Top

Exploring MyLabel

What kind of things can a MyLabel object do? Well, since we know that every MyLabel is also a Label, we can turn the Sun JavaDocs to find out. [This repeats the exercise in Lesson 1].

As you can see, the Label class has six methods:

The JavaDoc documentation for the Methods available in the Label class.
Back to Top

Trying Out

Let's see if this is really correct; let's see if a MyLabel really can do everything that a Label can. We'll just build a simple applet to find out. The applet will create a couple MyLabel objects, and then try out some of these "inherited" methods.

Create a new applet named TestML1.java, and then add the following code. When you're done, create an HTML file and try it out in appletviewer.
TestML1.java
import java.awt.*;
import java.applet.*;

public class TestML1 extends Applet
{
Label one = new MyLabel();
MyLabel two = new MyLabel();

public void init()
{
setLayout(new BorderLayout());
add(one, "North");
add(two, "South");

one.setText("I'm the top");
one.setAlignment(MyLabel.RIGHT);

two.setText("I'm the foundation");
two.setAlignment(Label.LEFT);
}
}

Back to Top

Lessons Learned

You don't get any compiler errors, and, as you can see from the running applet that appears just below the listing, it runs just fine.

There are four lessons we can draw from this program:

  1. A MyLabel object is a Label. The compiler gave us no complaints when we created the field one, which declares that it is a Label, not a MyLabel variable, yet assigned a MyLabel object.

  2. We can create MyLabel variables, such as two, just like we can create Label variables.

  3. We can automatically use the Label methods, setText() and setAlignment() without doing any extra work at all. The MyLabel class inherits them "for free."

  4. The MyLabel class also inherits the public fields defined in the Label class. Note that we can refer to either Label.RIGHT, or MyLabel.RIGHT. We could not, however, write TestML1.RIGHT or simply RIGHT, because TestML1 is not a Label, but MyLabel is a Label.
Back to Top

Where's the Rest?

As you may have noticed, the Label class only seems to have six methods. Where are the rest of the methods? If you look at the top of the Label class documentation, you'll see this:

The inheritance hierarchy in the JavaDoc documentation for the Label class.

The documentation for every class shows this ladder of inheritance. Looking at this ladder, you can see that java.awt.Label is a subclass of java.awt.Component, which is a subclass of java.lang.Object.

By clicking on the java.awt.Component hyperlink, the JavaDocs will take you to the documentation for the Label's superclass.

In the next section, we'll take a look at some of the most useful methods that our MyLabel class has inherited from its "grandparent".

Something to Talk About

Type in and compile the program TestML1.java shown earlier in this section. Now, change the definition of the field two so that a new Label object is assigned to the two variable. Does it compile? If not, then how do you explain it? If so, how do you explain that?

Please continue to the next section of this lesson.

 

Back to Top

 

Content Developed by Stephen Gilbert, Licensed under a Creative Commons License
Published by the Sofia Open Content Initiative
© 2004 Foothill-De Anza Community College District &The William and Flora Hewlett Foundation