- •CONTENTS
- •1.1 Introduction
- •1.2 What Is a Computer?
- •1.3 Programs
- •1.4 Operating Systems
- •1.5 Java, World Wide Web, and Beyond
- •1.6 The Java Language Specification, API, JDK, and IDE
- •1.7 A Simple Java Program
- •1.8 Creating, Compiling, and Executing a Java Program
- •1.9 (GUI) Displaying Text in a Message Dialog Box
- •2.1 Introduction
- •2.2 Writing Simple Programs
- •2.3 Reading Input from the Console
- •2.4 Identifiers
- •2.5 Variables
- •2.7 Named Constants
- •2.8 Numeric Data Types and Operations
- •2.9 Problem: Displaying the Current Time
- •2.10 Shorthand Operators
- •2.11 Numeric Type Conversions
- •2.12 Problem: Computing Loan Payments
- •2.13 Character Data Type and Operations
- •2.14 Problem: Counting Monetary Units
- •2.15 The String Type
- •2.16 Programming Style and Documentation
- •2.17 Programming Errors
- •2.18 (GUI) Getting Input from Input Dialogs
- •3.1 Introduction
- •3.2 boolean Data Type
- •3.3 Problem: A Simple Math Learning Tool
- •3.4 if Statements
- •3.5 Problem: Guessing Birthdays
- •3.6 Two-Way if Statements
- •3.7 Nested if Statements
- •3.8 Common Errors in Selection Statements
- •3.9 Problem: An Improved Math Learning Tool
- •3.10 Problem: Computing Body Mass Index
- •3.11 Problem: Computing Taxes
- •3.12 Logical Operators
- •3.13 Problem: Determining Leap Year
- •3.14 Problem: Lottery
- •3.15 switch Statements
- •3.16 Conditional Expressions
- •3.17 Formatting Console Output
- •3.18 Operator Precedence and Associativity
- •3.19 (GUI) Confirmation Dialogs
- •4.1 Introduction
- •4.2 The while Loop
- •4.3 The do-while Loop
- •4.4 The for Loop
- •4.5 Which Loop to Use?
- •4.6 Nested Loops
- •4.7 Minimizing Numeric Errors
- •4.8 Case Studies
- •4.9 Keywords break and continue
- •4.10 (GUI) Controlling a Loop with a Confirmation Dialog
- •5.1 Introduction
- •5.2 Defining a Method
- •5.3 Calling a Method
- •5.4 void Method Example
- •5.5 Passing Parameters by Values
- •5.6 Modularizing Code
- •5.7 Problem: Converting Decimals to Hexadecimals
- •5.8 Overloading Methods
- •5.9 The Scope of Variables
- •5.10 The Math Class
- •5.11 Case Study: Generating Random Characters
- •5.12 Method Abstraction and Stepwise Refinement
- •6.1 Introduction
- •6.2 Array Basics
- •6.3 Problem: Lotto Numbers
- •6.4 Problem: Deck of Cards
- •6.5 Copying Arrays
- •6.6 Passing Arrays to Methods
- •6.7 Returning an Array from a Method
- •6.8 Variable-Length Argument Lists
- •6.9 Searching Arrays
- •6.10 Sorting Arrays
- •6.11 The Arrays Class
- •7.1 Introduction
- •7.2 Two-Dimensional Array Basics
- •7.3 Processing Two-Dimensional Arrays
- •7.4 Passing Two-Dimensional Arrays to Methods
- •7.5 Problem: Grading a Multiple-Choice Test
- •7.6 Problem: Finding a Closest Pair
- •7.7 Problem: Sudoku
- •7.8 Multidimensional Arrays
- •8.1 Introduction
- •8.2 Defining Classes for Objects
- •8.3 Example: Defining Classes and Creating Objects
- •8.4 Constructing Objects Using Constructors
- •8.5 Accessing Objects via Reference Variables
- •8.6 Using Classes from the Java Library
- •8.7 Static Variables, Constants, and Methods
- •8.8 Visibility Modifiers
- •8.9 Data Field Encapsulation
- •8.10 Passing Objects to Methods
- •8.11 Array of Objects
- •9.1 Introduction
- •9.2 The String Class
- •9.3 The Character Class
- •9.4 The StringBuilder/StringBuffer Class
- •9.5 Command-Line Arguments
- •9.6 The File Class
- •9.7 File Input and Output
- •9.8 (GUI) File Dialogs
- •10.1 Introduction
- •10.2 Immutable Objects and Classes
- •10.3 The Scope of Variables
- •10.4 The this Reference
- •10.5 Class Abstraction and Encapsulation
- •10.6 Object-Oriented Thinking
- •10.7 Object Composition
- •10.8 Designing the Course Class
- •10.9 Designing a Class for Stacks
- •10.10 Designing the GuessDate Class
- •10.11 Class Design Guidelines
- •11.1 Introduction
- •11.2 Superclasses and Subclasses
- •11.3 Using the super Keyword
- •11.4 Overriding Methods
- •11.5 Overriding vs. Overloading
- •11.6 The Object Class and Its toString() Method
- •11.7 Polymorphism
- •11.8 Dynamic Binding
- •11.9 Casting Objects and the instanceof Operator
- •11.11 The ArrayList Class
- •11.12 A Custom Stack Class
- •11.13 The protected Data and Methods
- •11.14 Preventing Extending and Overriding
- •12.1 Introduction
- •12.2 Swing vs. AWT
- •12.3 The Java GUI API
- •12.4 Frames
- •12.5 Layout Managers
- •12.6 Using Panels as Subcontainers
- •12.7 The Color Class
- •12.8 The Font Class
- •12.9 Common Features of Swing GUI Components
- •12.10 Image Icons
- •13.1 Introduction
- •13.2 Exception-Handling Overview
- •13.3 Exception-Handling Advantages
- •13.4 Exception Types
- •13.5 More on Exception Handling
- •13.6 The finally Clause
- •13.7 When to Use Exceptions
- •13.8 Rethrowing Exceptions
- •13.9 Chained Exceptions
- •13.10 Creating Custom Exception Classes
- •14.1 Introduction
- •14.2 Abstract Classes
- •14.3 Example: Calendar and GregorianCalendar
- •14.4 Interfaces
- •14.5 Example: The Comparable Interface
- •14.6 Example: The ActionListener Interface
- •14.7 Example: The Cloneable Interface
- •14.8 Interfaces vs. Abstract Classes
- •14.9 Processing Primitive Data Type Values as Objects
- •14.10 Sorting an Array of Objects
- •14.11 Automatic Conversion between Primitive Types and Wrapper Class Types
- •14.12 The BigInteger and BigDecimal Classes
- •14.13 Case Study: The Rational Class
- •15.1 Introduction
- •15.2 Graphical Coordinate Systems
- •15.3 The Graphics Class
- •15.4 Drawing Strings, Lines, Rectangles, and Ovals
- •15.5 Case Study: The FigurePanel Class
- •15.6 Drawing Arcs
- •15.7 Drawing Polygons and Polylines
- •15.8 Centering a String Using the FontMetrics Class
- •15.9 Case Study: The MessagePanel Class
- •15.10 Case Study: The StillClock Class
- •15.11 Displaying Images
- •15.12 Case Study: The ImageViewer Class
- •16.1 Introduction
- •16.2 Event and Event Source
- •16.3 Listeners, Registrations, and Handling Events
- •16.4 Inner Classes
- •16.5 Anonymous Class Listeners
- •16.6 Alternative Ways of Defining Listener Classes
- •16.7 Problem: Loan Calculator
- •16.8 Window Events
- •16.9 Listener Interface Adapters
- •16.10 Mouse Events
- •16.11 Key Events
- •16.12 Animation Using the Timer Class
- •17.1 Introduction
- •17.2 Buttons
- •17.3 Check Boxes
- •17.4 Radio Buttons
- •17.5 Labels
- •17.6 Text Fields
- •17.7 Text Areas
- •17.8 Combo Boxes
- •17.9 Lists
- •17.10 Scroll Bars
- •17.11 Sliders
- •17.12 Creating Multiple Windows
- •18.1 Introduction
- •18.2 Developing Applets
- •18.3 The HTML File and the <applet> Tag
- •18.4 Applet Security Restrictions
- •18.5 Enabling Applets to Run as Applications
- •18.6 Applet Life-Cycle Methods
- •18.7 Passing Strings to Applets
- •18.8 Case Study: Bouncing Ball
- •18.9 Case Study: TicTacToe
- •18.10 Locating Resources Using the URL Class
- •18.11 Playing Audio in Any Java Program
- •18.12 Case Study: Multimedia Animations
- •19.1 Introduction
- •19.2 How is I/O Handled in Java?
- •19.3 Text I/O vs. Binary I/O
- •19.4 Binary I/O Classes
- •19.5 Problem: Copying Files
- •19.6 Object I/O
- •19.7 Random-Access Files
- •20.1 Introduction
- •20.2 Problem: Computing Factorials
- •20.3 Problem: Computing Fibonacci Numbers
- •20.4 Problem Solving Using Recursion
- •20.5 Recursive Helper Methods
- •20.6 Problem: Finding the Directory Size
- •20.7 Problem: Towers of Hanoi
- •20.8 Problem: Fractals
- •20.9 Problem: Eight Queens
- •20.10 Recursion vs. Iteration
- •20.11 Tail Recursion
- •APPENDIXES
- •INDEX
374 Chapter 11 Inheritance and Polymorphism
11.1 Introduction
Object-oriented programming allows you to derive new classes from existing classes. This is why inheritance? called inheritance. Inheritance is an important and powerful feature in Java for reusing software. Suppose you are to define classes to model circles, rectangles, and triangles. These classes have many common features. What is the best way to design these classes so to avoid redundancy and make the system easy to comprehend and easy to maintain? The answer is to
use inheritance.
11.2 Superclasses and Subclasses
Video Note
Geometric class hierarchy
You use a class to model objects of the same type. Different classes may have some common properties and behaviors, which can be generalized in a class that can be shared by other classes. Inheritance enables you to define a general class and later extend it to more specialized classes. The specialized classes inherit the properties and methods from the general class.
Consider geometric objects. Suppose you want to design the classes to model geometric objects such as circles and rectangles. Geometric objects have many common properties and behaviors. They can be drawn in a certain color, filled or unfilled. Thus a general class
GeometricObject |
|
|
|
|
|
-color: String |
|
The color of the object (default: white). |
-filled: boolean |
|
Indicates whether the object is filled with a color (default: false). |
-dateCreated: java.util.Date |
|
The date when the object was created. |
|
|
|
+GeometricObject() |
|
Creates a GeometricObject. |
+GeometricObject(color: String, |
|
Creates a GeometricObject with the specified color and filled |
filled: boolean) |
|
values. |
+getColor(): String |
|
Returns the color. |
+setColor(color: String): void |
|
Sets a new color. |
+isFilled(): boolean |
|
Returns the filled property. |
+setFilled(filled: boolean): void |
|
Sets a new filled property. |
+getDateCreated(): java.util.Date |
|
Returns the dateCreated. |
+toString(): String |
|
Returns a string representation of this object. |
|
|
|
Circle
-radius: double
+Circle() +Circle(radius: double)
+Circle(radius: double, color: String, filled: boolean)
+getRadius(): double
+setRadius(radius: double): void +getArea(): double +getPerimeter(): double +getDiameter(): double +printCircle(): void
Rectangle
-width: double -height: double
+Rectangle()
+Rectangle(width: double, height: double)
+Rectangle(width: double, height: double color: String, filled: boolean)
+getWidth(): double +setWidth(width: double): void +getHeight(): double +setHeight(height: double): void +getArea(): double +getPerimeter(): double
FIGURE 11.1 The GeometricObject class is the superclass for Circle and Rectangle.
11.2 Superclasses and Subclasses 375
GeometricObject can be used to model all geometric objects. This class contains the properties color and filled and their appropriate get and set methods. Assume that this class also contains the dateCreated property and the getDateCreated() and toString() methods. The toString() method returns a string representation for the object. Since a circle is a special type of geometric object, it shares common properties and methods with other geometric objects. Thus it makes sense to define the Circle class that extends the GeometricObject class. Likewise, Rectangle can also be declared as a subclass of GeometricObject. Figure 11.1 shows the relationship among these classes. An arrow pointing to the superclass is used to denote the inheritance relationship between the two classes involved.
In Java terminology, a class C1 extended from another class C2 is called a subclass, and C2 is called a superclass. A superclass is also referred to as a parent class, or a base class, and a subclass as a child class, an extended class, or a derived class. A subclass inherits accessible data fields and methods from its superclass and may also add new data fields and methods.
The Circle class inherits all accessible data fields and methods from the GeometricObject class. In addition, it has a new data field, radius, and its associated get and set methods. It also contains the getArea(), getPerimeter(), and getDiameter() methods for returning the area, perimeter, and diameter of the circle.
The Rectangle class inherits all accessible data fields and methods from the GeometricObject class. In addition, it has the data fields width and height and the associated get and set methods. It also contains the getArea() and getPerimeter() methods for returning the area and perimeter of the rectangle.
The GeometricObject, Circle, and Rectangle classes are shown in Listings 11.1, 11.2, and 11.3.
Note
To avoid naming conflict with the improved GeometricObject, Circle, and Rectangle classes introduced in the next chapter, name these classes GeometricObject1, Circle4, and Rectangle1 in this chapter. For convenience, we will still refer to them in the text as GeometricObject, Circle, and Rectangle classes. The best way to avoid naming conflict would be to place these classes in a different package. However, for simplicity and consistency, all classes in this book are placed in the default package.
subclass
superclass
avoid naming conflict
LISTING 11.1 GeometricObject1.java
1 |
public class GeometricObject1 { |
|
2 |
private String color = "white"; |
data fields |
3private boolean filled;
4 private java.util.Date dateCreated;
5
6/** Construct a default geometric object */
7 |
public GeometricObject1() { |
constructor |
|
8 |
|
dateCreated = new java.util.Date(); |
date constructed |
9 |
} |
|
|
10
11/** Construct a geometric object with the specified color
12* and filled value */
13public GeometricObject1(String Color, boolean filled) {
14dateCreated = new java.util.Date();
15this.color = color;
16this.filled = filled;
17}
18
19/** Return color */
20public String getColor() {
21return color;
22}
376 Chapter 11 |
Inheritance and Polymorphism |
|||
|
23 |
|
|
|
|
24 |
/** Set a new color */ |
||
|
25 |
public void setColor(String color) { |
||
|
26 |
this.color = color; |
||
|
27 |
} |
|
|
|
28 |
|
|
|
|
29 |
/** Return filled. Since filled is boolean, |
||
|
30 |
its get method is named isFilled */ |
||
|
31 |
public boolean isFilled() { |
||
|
32 |
return filled; |
||
|
33 |
} |
|
|
|
34 |
|
|
|
|
35 |
/** Set a new filled */ |
||
|
36 |
public void setFilled(boolean filled) { |
||
|
37 |
this.filled = filled; |
||
|
38 |
} |
|
|
|
39 |
|
|
|
|
40 |
/** Get dateCreated */ |
||
|
41 |
public java.util.Date getDateCreated() { |
||
|
42 |
return dateCreated; |
||
|
43 |
} |
|
|
|
44 |
|
|
|
|
45 |
/** Return a string representation of this object */ |
||
|
46 |
public String toString() { |
||
|
47 |
return "created on " + dateCreated + "\ncolor: " + color + |
||
|
48 |
" and filled: " + filled; |
||
|
49 |
} |
|
|
|
50 |
} |
|
|
|
LISTING 11.2 Circle4.java |
|||
|
|
|
||
|
1 |
public class Circle4 |
extends GeometricObject1 |
{ |
data fields |
2 |
private double radius; |
||
|
3 |
|
|
|
constructor |
4 |
public Circle4() { |
||
|
5 |
} |
|
|
|
6 |
|
|
|
|
7 |
public Circle4(double radius) { |
||
|
8 |
this.radius = radius; |
||
|
9 |
} |
|
|
|
10 |
|
|
|
|
11 |
public Circle4(double radius, String color, boolean filled) { |
||
methods |
12 |
this.radius = radius; |
||
|
13 |
setColor(color); |
||
|
14 |
setFilled(filled); |
||
|
15 |
} |
|
|
|
16 |
|
|
|
|
17 |
/** Return radius */ |
||
|
18 |
public double getRadius() { |
||
|
19 |
return radius; |
||
|
20 |
} |
|
|
|
21 |
|
|
|
|
22 |
/** Set a new radius */ |
||
|
23 |
public void setRadius(double radius) { |
||
|
24 |
this.radius = radius; |
||
|
25 |
} |
|
|
|
26 |
|
|
|
|
27 |
/** Return area */ |
||
|
28 |
public double getArea() { |
||
|
29 |
return radius * radius * Math.PI; |
||
|
30 |
} |
|
|
11.2 Superclasses and Subclasses 377
31
32/** Return diameter */
33public double getDiameter() {
34return 2 * radius;
35}
36
37/** Return perimeter */
38public double getPerimeter() {
39return 2 * radius * Math.PI;
40}
41
42/* Print the circle info */
43public void printCircle() {
44System.out.println("The circle is created " + getDateCreated() +
45" and the radius is " + radius);
46}
47}
The Circle class extends the GeometricObject class (Listing 11.2) using the following syntax:
Subclass |
Superclass |
public class Circle extends GeometricObject
The keyword extends (line 1) tells the compiler that the Circle class extends the
GeometricObject class, thus inheriting the methods getColor, setColor, isFilled, setFilled, and toString.
The overloaded constructor Circle(double radius, string color, boolean filled) is implemented by invoking the setColor and setFilled methods to set the color and filled properties (lines 11–15). These two public methods are defined in the base class GeometricObject and are inherited in Circle. So, they can be used in the derived class.
You might attempt to use the data fields color and filled directly in the constructor as private member in base class follows:
public Circle4(double radius, String color, boolean filled) { this.radius = radius;
this.color = color; // Illegal this.filled = filled; // Illegal
}
This is wrong, because the private data fields color and filled in the GeometricObject class cannot be accessed in any class other than in the GeometricObject class itself. The only way to read and modify color and filled is through their get and set methods.
The Rectangle class (Listing 11.3) extends the GeometricObject class (Listing 11.2) using the following syntax:
Subclass Superclass
public class Rectangle extends GeometricObject
378 Chapter 11 Inheritance and Polymorphism
The keyword extends (line 1) tells the compiler that the Rectangle class extends the
GeometricObject class, thus inheriting the methods getColor, setColor, isFilled, setFilled, and toString.
LISTING 11.3 Rectangle1.java
|
1 |
public class Rectangle1 extends GeometricObject1 { |
|
data fields |
2 |
private double width; |
|
|
3 |
private double height; |
|
|
4 |
|
|
constructor |
5 |
public Rectangle1() { |
|
|
6 |
} |
|
|
7 |
|
|
|
8 |
public Rectangle1(double width, double height) { |
|
|
9 |
this.width = width; |
|
|
10 |
this.height = height; |
|
|
11 |
} |
|
|
12 |
|
|
|
13 |
public Rectangle1(double width, double height, String color, |
|
|
14 |
boolean filled) { |
|
|
15 |
this.width = width; |
|
|
16 |
this.height = height; |
|
|
17 |
setColor(color); |
|
|
18 |
setFilled(filled); |
|
|
19 |
} |
|
|
20 |
|
|
|
21 |
/** Return width */ |
|
methods |
22 |
public double getWidth() { |
|
|
23 |
return width; |
|
|
24 |
} |
|
|
25 |
|
|
|
26 |
/** Set a new width */ |
|
|
27 |
public void setWidth(double width) { |
|
|
28 |
this.width = width; |
|
|
29 |
} |
|
|
30 |
|
|
|
31 |
/** Return height */ |
|
|
32 |
public double getHeight() { |
|
|
33 |
return height; |
|
|
34 |
} |
|
|
35 |
|
|
|
36 |
/** Set a new height */ |
|
|
37 |
public void setHeight(double height) { |
|
|
38 |
this.height = height; |
|
|
39 |
} |
|
|
40 |
|
|
|
41 |
/** Return area */ |
|
|
42 |
public double getArea() { |
|
|
43 |
return width * height; |
|
|
44 |
} |
|
|
45 |
|
|
|
46 |
/** Return perimeter */ |
|
|
47 |
public double getPerimeter() { |
|
|
48 |
return 2 * (width + height); |
|
|
49 |
} |
|
|
50 |
} |
|
The code in Listing 11.4 creates objects of Circle and Rectangle and invokes the methods on these objects. The toString() method is inherited from the GeometricObject class and is invoked from a Circle object (line 4) and a Rectangle object (line 10).
11.2 Superclasses and Subclasses 379
LISTING 11.4 TestCircleRectangle.java
1 public class TestCircleRectangle {
2public static void main(String[] args) {
3 |
|
Circle4 circle = new Circle4(1); |
|
|
|
|
|
Circle object |
4 |
System.out.println("A circle " + |
|
circle.toString() |
); |
invoke toString |
|||
5 |
System.out.println("The radius is " + |
circle.getRadius() |
); |
|
6System.out.println("The area is " + circle.getArea());
7 |
System.out.println("The diameter is " + |
circle.getDiameter() |
); |
|
||||
8 |
|
|
|
|
|
|
|
|
9 |
|
Rectangle1 rectangle = new Rectangle1(2, 4); |
|
|
Rectangle object |
|||
10 |
System.out.println("\nA rectangle " + |
rectangle.toString() |
); |
invoke toString |
11System.out.println("The area is " + rectangle.getArea());
12System.out.println("The perimeter is " +
13rectangle.getPerimeter() );
14}
15}
A circle created on Thu Sep 24 20:31:02 EDT 2009 color: white and filled: false
The radius is 1.0
The area is 3.141592653589793 The diameter is 2.0
A rectangle created on Thu Sep 24 20:31:02 EDT 2009 color: white and filled: false
The area is 8.0
The perimeter is 12.0
The following points regarding inheritance are worthwhile to note: |
|
■ Contrary to the conventional interpretation, a subclass is not a subset of its super- |
|
class. In fact, a subclass usually contains more information and methods than its |
more in subclass |
superclass. |
|
■ Private data fields in a superclass are not accessible outside the class. Therefore, they |
private data fields |
cannot be used directly in a subclass. They can, however, be accessed/mutated |
|
through public accessor/mutator if defined in the superclass. |
|
■ Not all is-a relationships should be modeled using inheritance. For example, a |
nonextensible is-a |
square is a rectangle, but you should not define a Square class to extend a |
|
Rectangle class, because there is nothing to extend (or supplement) from a rec- |
|
tangle to a square. Rather you should define a Square class to extend the |
|
GeometricObject class. For class A to extend class B, A should contain more |
|
detailed information than B. |
|
■ Inheritance is used to model the is-a relationship. Do not blindly extend a class just |
no blind extension |
for the sake of reusing methods. For example, it makes no sense for a Tree class to |
|
extend a Person class, even though they share common properties such as height |
|
and weight. A subclass and its superclass must have the is-a relationship. |
|
■ Some programming languages allow you to derive a subclass from several classes. |
|
This capability is known as multiple inheritance. Java, however, does not allow mul- |
multiple inheritance |
tiple inheritance. A Java class may inherit directly from only one superclass. This |
|
restriction is known as single inheritance. If you use the extends keyword to define |
single inheritance |
a subclass, it allows only one parent class. Nevertheless, multiple inheritance can be |
|
achieved through interfaces, which will be introduced in §14.4, “Interfaces.” |
|