Making the Most of Existing Objects - Working with Information in New Ways - Sams Teach Yourself Java in 24 Hours, 7th Edition (2014)

Sams Teach Yourself Java in 24 Hours, 7th Edition (2014)

Part III: Working with Information in New Ways

Hour 12. Making the Most of Existing Objects

THIS HOUR’S TO-DO LIST:

Image Design superclasses and subclasses.

Image Form an inheritance hierarchy.

Image Override methods.

Java objects are ideally suited for childbearing. When you create an object—a set of attributes and behavior—you have designed something that’s ready to pass these qualities on to offspring. These child objects take on a lot of the same attributes and behavior of the parent. They also can do some things differently than the parent.

This system is called inheritance, and it’s something every superclass (parent) gives to its subclasses (children). Inheritance is one of the most useful aspects of object-oriented programming (OOP), and you learn about it during this hour.

Another useful aspect of OOP is the capability to create an object that you can use with different programs. Reusability makes it easier to develop error-free, reliable programs.

The Power of Inheritance

You have used inheritance every time you worked with one of the standard Java classes such as String or Integer. Java classes are organized into a pyramid-shaped hierarchy of classes in which all classes descend from the Object class.

A class of objects inherits from all superclasses that are above it. To get a working idea of how this operates, consider the JApplet class. This class is a superclass of all applets, browser-based Java programs that use a graphical user interface framework called Swing. The JApplet class is a subclass of Applet.

A partial family tree of JApplet is shown in Figure 12.1. Each of the boxes is a class, and the lines connect a superclass to any subclasses below it.

Image

FIGURE 12.1 The family tree of the JApplet class.

At the top is the Object class. JApplet has five superclasses above it in the hierarchy: Applet, Panel, Container, Component, and Object.

The JApplet class inherits attributes and behavior from each of these classes because each is directly above it in the hierarchy of superclasses. JApplet does not inherit anything from the five green classes in Figure 12.1, which include Dialog and Frame, because they are not above it in the hierarchy.

If this seems confusing, think of the hierarchy as a family tree. JApplet inherits from its parent, the parent’s parent, and on upward. It even might inherit some things from its great-great-great-grandparent, Object. The JApplet class doesn’t inherit from its siblings or its cousins, however.

Creating a new class boils down to the following task: You only have to define the ways in which it is different from an existing class. The rest of the work is done for you.

Inheriting Behavior and Attributes

The behavior and attributes of a class are a combination of two things: its own behavior and attributes and all the behavior and attributes it inherits from its superclasses.

The following are some of the behavior and attributes of JApplet:

Image The equals() method determines whether a JApplet object has the same value as another object.

Image The setBackground() method sets the background color of the applet window.

Image The add() method adds user interface components such as buttons and text fields to the applet.

Image The setLayout() method defines how the applet’s graphical user interface is organized.

The JApplet class can use all these methods, even though setLayout() is the only one it didn’t inherit from another class. The equals() method is defined in Object, setBackground() comes from Component, and add() comes from Container.

Overriding Methods

Some methods defined in the JApplet class of objects also are defined in one of its superclasses. As an example, the update() method is part of both the JApplet class and the Component class. When a method is defined in a subclass and its superclass, the subclass method is used. This enables a subclass to change, replace, or completely wipe out some of the behavior or attributes of its superclasses. In the case of update(), the purpose is to wipe out some behavior present in a superclass.

Creating a new method in a subclass to change behavior inherited from a superclass is called overriding the method. You need to override a method any time the inherited behavior produces an undesired result.

Establishing Inheritance

A class is defined as the subclass of another class using the extends statement, as in the following:

class AnimatedLogo extends JApplet {
// behavior and attributes go here
}

The extends statement establishes the AnimatedLogo class of objects as a subclass of JApplet. All Swing applets must be subclasses of JApplet. They need the functionality this class provides to run when presented on a web page.

One method that AnimatedLogo must override is the paint() method, which is used to draw everything within the program’s window. The paint() method, implemented by the Component class, is passed all the way down to AnimatedLogo. However, the paint() method does not do anything. It exists so that subclasses of Component have a method they can use when something must be displayed.

To override a method, you must declare the method in the same way it was declared in the superclass from which it was inherited. A public method must remain public, the value sent back by the method must be the same, and the number and type of arguments to the method must not change.

The paint() method of the Component class begins as follows:

public void paint(Graphics g) {

When AnimatedLogo overrides this method, it must begin with a statement like this:

public void paint(Graphics screen) {

The only difference lies in the name of the Graphics object, which does not matter when determining if the methods are created in the same way. These two statements match because the following things match:

Image Both paint() methods are public.

Image Both methods return no value, as declared by the use of the void statement.

Image Both have a Graphics object as their only argument.

Using this and super in a Subclass

Two keywords that are extremely useful in a subclass are this and super.

As you learned during the previous hour, the this keyword is used to refer to the current object. When you’re creating a class and you need to refer to the specific object created from that class, you can use this, as in the following statement:

this.title = "Cagney";

This statement sets the object’s title variable to the text “Cagney.”

The super keyword serves a similar purpose: It refers to the immediate superclass of the object. You can use super in several different ways:

Image To refer to a constructor method of the superclass, as in super("Adam", 12);

Image To refer to a variable of the superclass, as in super.hawaii = 50

Image To refer to a method of the superclass, as in super.dragnet();

One way you use the super keyword is in the constructor of a subclass. Because a subclass inherits the behavior and attributes of its superclass, you have to associate each constructor of that subclass with a constructor of its superclass. Otherwise, some of the behavior and attributes might not be set up correctly, and the subclass isn’t able to function properly.

To associate the constructors, the first statement of a subclass constructor must be a call to a constructor of the superclass. This requires the super keyword, as in the following statements:

public DataReader(String name, int length) {
super(name, length);
}

This example is the constructor of a subclass, which is using the statement super(name, length) to call a comparable constructor in its superclass.

If you don’t use super() to call a constructor in the superclass, Java automatically calls super() with no arguments when the subclass constructor begins. If this superclass constructor doesn’t exist or provides unexpected behavior, errors will result, so it’s better to call a superclass constructor yourself.

Working with Existing Objects

OOP encourages reuse. If you develop an object for use with one Java programming project, it should be possible to incorporate that object into another project without modification.

If a Java class is well designed, it’s possible to make that class available for use in other programs. The more objects available for use in your programs, the less work you have to do when creating your own software. If there’s an excellent spell-checking object that suits your needs, you can use it instead of writing your own. Ideally, you can even give your boss a false impression about how long it took to add spell-checking functionality to your project and use this extra time to make personal long-distance calls from the office.


Note

The author of this book, like many in his profession, is self-employed and works out of his home. Please keep this in mind when evaluating his advice on how to conduct yourself in the workplace.


When Java was first introduced, the system of sharing objects was largely an informal one. Programmers developed their objects to be as independent as possible and protected them against misuse through the use of private variables and public methods to read and write those variables.

Sharing objects becomes more powerful when there’s a standard approach to developing reusable objects.

The benefits of a standard include the following:

Image There’s less need to document how an object works because anyone who knows the standard already knows a lot about how it functions.

Image You can design development tools that follow the standard, making it possible to work more easily with these objects.

Image Two objects that follow the standard are able to interact with each other without special programming to make them compatible.

Storing Objects of the Same Class in Array Lists

An important decision to make when writing a computer program is where to store data. In the first half of this book, you’ve discovered three useful places to keep information:

Image Basic data types such as int and char

Image Arrays

Image String objects

There are far more places to store information, because any Java class can hold data. One of the most useful is ArrayList, a data structure that holds objects of the same class.

As the class name suggests, array lists are like arrays, which also hold elements of related data, but they can grow or shrink in size at any time.

The ArrayList class belongs to the java.util package of classes, one of the most useful in the Java Class Library. An import statement makes it available in your program:

import java.util.ArrayList;

An array list holds objects that either belong to the same class or share the same superclass. They are created by referencing two classes: the ArrayList class and the class the list holds.

The name of the class held by the list is placed within < and > characters, as in this statement:

ArrayList<String> structure = new ArrayList<String>();

The preceding statement creates a list that holds strings. Identifying a list’s class in this manner utilizes generics, a way to indicate the kinds of objects a data structure such as an array list holds. If you were using lists with an older version of Java, you would have written a constructor like this:

ArrayList structure = new ArrayList();

Although you can still do this, generics make your code more reliable because they give the compiler a way to prevent more errors. Here, they stop you from misusing an array list by putting the wrong class of objects in it. If you attempt to put an Integer object in a list that’s supposed to hold String objects, the compiler fails with an error.

Unlike arrays, array lists aren’t created with a fixed number of elements they hold. The list is created with 10 elements. If you know you’re storing a lot more objects than that, you can specify a size as an argument to the constructor. Here’s a statement that creates a 300-element list:

ArrayList<String> structure = new ArrayList<String>(300);

You can add an object to a list by calling its add() method, using the object as the only argument:

structure.add("Vance");
structure.add("Vernon");
structure.add("Velma");

You add objects in order, so if these are the first three objects added to structure, element 0 is “Vance”, element 1 is “Vernon”, and element 2 is “Velma”.

You retrieve an element from a list by calling its get() method with the element’s index number as the argument:

String name = structure.get(1);

This statement stores “Vernon” in the name string.

To see if a list contains an object in one of its elements, call its contains() method with that object as an argument:

if (structure.contains("Velma")) {
System.out.println("Velma found");
}

You can remove an object from a list using itself or its index number:

structure.remove(0);
structure.remove("Vernon");

These two statements leave “Velma” as the only string in the list.

Looping Through an Array List

Java includes a special for loop that makes it easy to load an array list and examine each of its elements in turn.

This loop has just two parts, which is one less than the for loops you learned about in Hour 8, “Repeating an Action with Loops.”

The first part is the initialization section: the class and name of a variable that holds each object retrieved from the list. This object should belong to the same class that holds the list.

The second part identifies the list.

Here’s code that loops through the structure list, displaying each name to the screen:

for (String name : structure) {
System.out.println(name);
}

The hour’s first project takes array lists and the special for loop for a spin, presenting a list of strings in alphabetical order. The list comes from an array and command-line arguments.

With your Java24 project open within NetBeans, choose File, New File, and then create a new Empty Java File named StringLister. Enter Listing 12.1 in the source editor and save the file.

LISTING 12.1 The Full Text of StringLister.java


1: package com.java24hours;
2:
3: import java.util.*;
4:
5: public class StringLister {
6: String[] names = { "Spanky", "Alfalfa", "Buckwheat", "Daria",
7: "Stymie", "Marianne", "Scotty", "Tommy", "Chubby" };
8:
9: public StringLister(String[] moreNames) {
10: ArrayList<String> list = new ArrayList<String>();
11: for (int i = 0; i < names.length; i++) {
12: list.add(names[i]);
13: }
14: for (int i = 0; i < moreNames.length; i++) {
15: list.add(moreNames[i]);
16: }
17: Collections.sort(list);
18: for (String name : list) {
19: System.out.println(name);
20: }
21: }
22:
23: public static void main(String[] arguments) {
24: StringLister lister = new StringLister(arguments);
25: }
26: }


Before you run the application, you should use the Run, Set Project Configuration, Customize command to set the main class to StringLister and the argument to one or more names separated by spaces, such as Jackie Mickey Farina Woim. Then choose Run, Run Project to see the result.

The names specified at the command line are added to the names stored in an array in Lines 6–7. Because the total number of names is not known until the program runs, an array list serves as a better storage place for these strings than an array.

The list’s strings are sorted in alphabetical order using a method of the Collections class:

Collections.sort(list);

This class, like ArrayList, belongs to the java.util package. Array lists and other useful data structures are called collections in Java.

When you run the program, the output should be a list of names in alphabetical order (see Figure 12.2). The flexible size of array lists enables your additional names to be added to the data structure and sorted along with the others.

Image

FIGURE 12.2 The output of the StringLister program.

Creating a Subclass

To see an example of inheritance at work, in the next project you create a class called Point3D that represents a point in three-dimensional space. You can express a two-dimensional point with an (x,y) coordinate. Three-dimensional space adds a third coordinate, which can be called z.

The Point3D class of objects can do three things:

Image Keep track of an object’s (x,y,z) coordinate

Image Move an object to a new (x,y,z) coordinate

Image Move an object by a specified amount of x, y, and z values

Java already has a standard class that represents two-dimensional points called Point.

It has two integer variables called x and y that store a Point object’s (x,y) location. It also has a move() method to place a point at the specified location and a translate() method to move an object by an amount of x and y values.

In the Java24 project in NetBeans, create a new Empty Java File called Point3D and enter the text of Listing 12.2 into the file. Save it when you’re done.

LISTING 12.2 The Full Text of Point3D.java


1: package com.java24hours;
2:
3: import java.awt.*;
4:
5: public class Point3D extends Point {
6: public int z;
7:
8: public Point3D(int x, int y, int z) {
9: super(x,y);
10: this.z = z;
11: }
12:
13: public void move(int x, int y, int z) {
14: this.z = z;
15: super.move(x, y);
16: }
17:
18: public void translate(int x, int y, int z) {
19: this.z += z;
20: super.translate(x, y);
21: }
22: }


The Point3D class does not have a main() method, so you cannot run it as an application, but you can use it in Java programs anywhere a three-dimensional point is needed.

The Point3D class only has to do work that isn’t being done by its superclass, Point. This primarily involves keeping track of the integer variable z and receiving it as an argument to the move() method, translate() method, and Point3D() constructor.

All the methods use the keywords super and this. The this statement is used to refer to the current Point3D object, so this.z = z in Line 10 sets the object variable z equal to the z value that is sent as an argument to the method in Line 8.

The super statement refers to the current object’s superclass, Point. It is used to set variables and call methods that are inherited by Point3D. The statement super(x,y) in Line 9 calls the Point(x,y) constructor in the superclass, which then sets the (x,y) coordinates of thePoint3D object. Because Point already is equipped to handle the x and y axes, it would be redundant for the Point3D class of objects to do the same thing.

To test out the new Point3D class, create a program that uses Point and Point3D objects and moves them around. Create a new file in NetBeans called PointTester and enter Listing 12.3 into it. The file compiles automatically when it is saved.

LISTING 12.3 The Full Text of PointTester.java


1: package com.java24hours;
2:
3: import java.awt.*;
4:
5: class PointTester {
6: public static void main(String[] arguments) {
7: Point location1 = new Point(11,22);
8: Point3D location2 = new Point3D(7,6,64);
9:
10: System.out.println("The 2D point is at (" + location1.x
11: + ", " + location1.y + ")");
12: System.out.println("It's being moved to (4, 13)");
13: location1.move(4,13);
14: System.out.println("The 2D point is now at (" + location1.x
15: + ", " + location1.y + ")");
16: System.out.println("It's being moved -10 units on both the x "
17: + "and y axes");
18: location1.translate(-10,-10);
19: System.out.println("The 2D point ends up at (" + location1.x
20: + ", " + location1.y + ")\n");
21:
22: System.out.println("The 3D point is at (" + location2.x
23: + ", " + location2.y + ", " + location2.z + ")");
24: System.out.println("It's being moved to (10, 22, 71)");
25: location2.move(10,22,71);
26: System.out.println("The 3D point is now at (" + location2.x
27: + ", " + location2.y + ", " + location2.z + ")");
28: System.out.println("It's being moved -20 units on the x, y "
29: + "and z axes");
30: location2.translate(-20,-20,-20);
31: System.out.println("The 3D point ends up at (" + location2.x
32: + ", " + location2.y + ", " + location2.z + ")");
33: }
34: }


When you run the file by choosing Run, Run File, you see the output shown in Figure 12.3 if the program compiled properly. If not, look for the red alert icon alongside the source editor that indicates the line that triggered an error.

Image

FIGURE 12.3 The output of the PointTester program.

Summary

When people talk about the miracle of birth, they’re probably not speaking of the way a superclass in Java can give birth to subclasses or the way behavior and attributes are inherited in a hierarchy of classes.

If the real world worked the same way that OOP does, every descendant of Mozart could choose to be a brilliant composer. All descendants of Mark Twain could be poetic about Mississippi riverboat life. Every skill your ancestors worked to achieve would be handed to you without an ounce of toil.

On the scale of miracles, inheritance isn’t quite up to par with continuing the existence of a species or throwing consecutive no-hitters in baseball. However, it’s an effective way to design software with a minimum of redundant work.

Workshop

Q&A

Q. Most Java programs created up to this point have not used extends to inherit from a superclass. Does this mean they exist outside of the class hierarchy?

A. All classes you create in Java are part of the hierarchy because the default superclass for the programs you write is Object when you aren’t using the extends keyword. The equals() and toString() methods of all classes are part of the behavior that automatically is inherited from Object.

Q. Why do people yell “eureka!” when they’ve discovered something?

A. Eureka is borrowed from ancient Greek, where it meant “I have found it!” The phrase was supposedly exclaimed by the Greek scholar Archimedes when he stepped into a bath.

What did the Greek discover in the bathtub? The rising water level, which led him to understand that the volume of displaced water must equal the volume of his body parts.

The story about Archimedes was spread two centuries later by Vitruvius in his multivolume De Architectura, a book about architecture.

“Eureka” has been in the California state seal since 1849, referring to the discovery of gold near Sutter’s Mill a year earlier.

Quiz

To determine what kind of knowledge you inherited from the past hour’s work, answer the following questions.

1. If a superclass handles a method in a way you don’t want to use in the subclass, what can you do?

A. Delete the method in the superclass.

B. Override the method in the subclass.

C. Write a nasty letter to the editor of the San Jose Mercury News hoping that Java’s developers read it.

2. What methods can you use to retrieve an element stored in an array list?

A. get()

B. read()

C. elementAt()

3. What statement can you use to refer to the methods and variables of the current object?

A. this

B. that

C. theOther

Answers

1. B. Because you can override the method, you don’t have to change any aspect of the superclass or the way it works.

2. A. The get() method has one argument—the index number of the element.

3. A. The this keyword refers to the object in which it appears.

Activities

If a fertile imagination has birthed in you a desire to learn more, you can spawn more knowledge of inheritance with the following activities:

Image Create a Point4D class that adds a t coordinate to the (x,y,z) coordinate system created by the Point3D class. The t coordinate stands for time, so you need to ensure that it is never set to a negative value.

Image Take the members of a football team’s offense: lineman, wide receiver, tight end, running back, and quarterback. Design a hierarchy of classes that represent the skills of these players, putting common skills higher up in the hierarchy. For example, blocking is behavior that probably should be inherited by the linemen and tight end classes, and speed is something that should be inherited by wide receivers and running backs.

To see Java programs that implement these activities, visit the book’s website at www.java24hours.com.