- •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
458 Chapter 14 Abstract Classes and Interfaces
|
14.1 Introduction |
|
You have learned how to write simple programs to create and display GUI components. Can you |
|
write the code to respond to user actions, such as clicking a button? As shown in Figure 14.1, |
problem |
when a button is clicked, a message is displayed on the console. |
FIGURE 14.1 The program responds to button-clicking action events.
In order to write such code, you have to know interfaces. An interface is for defining common behavior for classes (especially unrelated classes). Before discussing interfaces, we introduce a closely related subject: abstract classes.
Video Note
Abstract Geometric-
Object Class
abstract class
abstract method abstract modifier
abstract class
14.2 Abstract Classes
In the inheritance hierarchy, classes become more specific and concrete with each new subclass. If you move from a subclass back up to a superclass, the classes become more general and less specific. Class design should ensure that a superclass contains common features of its subclasses. Sometimes a superclass is so abstract that it cannot have any specific instances. Such a class is referred to as an abstract class.
In Chapter 11, GeometricObject was defined as the superclass for Circle and Rectangle. GeometricObject models common features of geometric objects. Both
Circle and Rectangle contain the getArea() and getPerimeter() methods for computing the area and perimeter of a circle and a rectangle. Since you can compute areas and perimeters for all geometric objects, it is better to define the getArea() and getPerimeter() methods in the GeometricObject class. However, these methods cannot be implemented in the GeometricObject class, because their implementation depends on the specific type of geometric object. Such methods are referred to as abstract methods and are denoted using the abstract modifier in the method header. After you define the methods in GeometricObject, it becomes an abstract class. Abstract classes are denoted using the abstract modifier in the class header. In UML graphic notation, the names of abstract classes and their abstract methods are italicized, as shown in Figure 14.2. Listing 14.1 gives the source code for the new GeometricObject class.
LISTING 14.1 GeometricObject.java
1 public abstract class GeometricObject {
2 private String color = "white";
3private boolean filled;
4 private java.util.Date dateCreated;
5
6 /** Construct a default geometric object */
7protected GeometricObject() {
8 dateCreated = new java.util.Date();
9 }
10
11/** Construct a geometric object with color and filled value */
12protected GeometricObject(String color, boolean filled) {
13dateCreated = new java.util.Date();
14.2 Abstract Classes 459
|
|
|
|
GeometricObject |
||
|
|
|
|
|
|
|
|
|
|
|
-color: String |
||
|
|
|
|
-filled: boolean |
||
|
|
|
|
-dateCreated: java.util.Date |
||
The # sign indicates |
|
|
|
|
|
|
|
#GeometricObject() |
|||||
protected modifier |
|
|||||
|
#GeometricObject(color: string, |
|||||
|
|
|
|
|||
|
|
|
|
filled: boolean) |
||
|
|
|
|
+getColor(): String |
||
|
|
|
|
+setColor(color: String): void |
||
|
|
|
|
+isFilled(): boolean |
||
|
|
|
|
+setFilled(filled: boolean): void |
||
|
|
|
|
+getDateCreated(): java.util.Date |
||
|
|
|
|
+toString(): String |
||
|
|
|
|
|
|
|
Abstract methods |
|
|
|
+getArea(): double |
||
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
+getPerimeter(): double |
|
||
are italicized |
|
|
||||
|
|
|
|
Abstract class
Methods getArea and getPerimeter are overridden in Circle and Rectangle. Superclass methods are generally omitted in the UML diagram for subclasses.
Circle
-radius: double
+Circle() +Circle(radius: double)
+Circle(radius: double, color. string, filled: boolean)
+getRadius(): double +setRadius(radius: double): void +getDiameter(): double
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
FIGURE 14.2 The new GeometricObject class contains abstract methods.
14this.color = color;
15this.filled = filled;
16}
17
18/** Return color */
19public String getColor() {
20return color;
21}
22
23/** Set a new color */
24public void setColor(String color) {
25this.color = color;
26}
27
28/** Return filled. Since filled is boolean,
29* the get method is named isFilled */
30public boolean isFilled() {
31return filled;
32}
33
460 Chapter 14 |
Abstract Classes and Interfaces |
||||
|
34 |
|
/** Set a new filled */ |
||
|
35 |
|
public void setFilled(boolean filled) { |
||
|
36 |
|
this.filled = filled; |
||
|
37 |
} |
|
|
|
|
38 |
|
|
|
|
|
39 |
|
/** Get dateCreated */ |
||
|
40 |
|
public java.util.Date getDateCreated() { |
||
|
41 |
|
return dateCreated; |
||
|
42 |
} |
|
|
|
|
43 |
|
|
|
|
|
44 |
|
/** Return a string representation of this object */ |
||
|
45 |
|
public String toString() { |
||
|
46 |
|
return "created on " + dateCreated + "\ncolor: " + color + |
||
|
47 |
|
" and filled: " + filled; |
||
|
48 |
} |
|
|
|
|
49 |
|
|
|
|
|
50 |
|
/** Abstract method getArea */ |
||
abstract method |
51 |
|
public abstract double getArea(); |
|
|
|
52 |
|
|
|
|
|
53 |
|
/** Abstract method getPerimeter */ |
||
abstract method |
54 |
|
public abstract double getPerimeter(); |
|
|
|
55 |
} |
|
|
|
why protected constructor?
implementing Circle implementing Rectangle
extends abstract
GeometricObject
Abstract classes are like regular classes, but you cannot create instances of abstract classes using the new operator. An abstract method is defined without implementation. Its implementation is provided by the subclasses. A class that contains abstract methods must be defined abstract.
The constructor in the abstract class is defined protected, because it is used only by subclasses. When you create an instance of a concrete subclass, its superclass’s constructor is invoked to initialize data fields defined in the superclass.
The GeometricObject abstract class defines the common features (data and methods) for geometric objects and provides appropriate constructors. Because you don’t know how to compute areas and perimeters of geometric objects, getArea and getPerimeter are defined as abstract methods. These methods are implemented in the subclasses. The implementation of Circle and Rectangle is the same as in Listings 14.2 and 14.3, except that they extend the GeometricObject class defined in this chapter, as follows:
LISTING 14.2 Circle.java
1 public class Circle extends GeometricObject {
2 // Same as lines 2-46 in Listing 11.2, so omitted 3 }
LISTING 14.3 Rectangle.java
extends abstract |
1 |
public class Rectangle |
extends GeometricObject |
{ |
GeometricObject |
2 |
// Same as lines 2-49 in Listing 11.3, so omitted |
||
|
3 |
} |
|
|
14.2.1Why Abstract Methods?
You may be wondering what advantage is gained by defining the methods getArea and getPerimeter as abstract in the GeometricObject class instead of defining them only in each subclass. The following example shows the benefits of defining them in the
GeometricObject class.
The example in Listing 14.4 creates two geometric objects, a circle and a rectangle, invokes the equalArea method to check whether they have equal areas and invokes the displayGeometricObject method to display them.
14.2 Abstract Classes 461
LISTING 14.4 TestGeometricObject.java
1 public class TestGeometricObject {
2/** Main method */
3 public static void main(String[] args) {
4// Create two geometric objects
5 |
|
GeometricObject geoObject1 = new Circle(5); |
|
create a circle |
||||
6 |
|
GeometricObject geoObject2 = new Rectangle(5, 3); |
|
create a rectangle |
||||
7 |
|
|
|
|
|
|
|
|
8 |
System.out.println("The |
two objects have the same area? " + |
|
|||||
9 |
|
|
equalArea(geoObject1, |
geoObject2) |
); |
|
|
|
10
11// Display circle
12displayGeometricObject(geoObject1);
14// Display rectangle
15displayGeometricObject(geoObject2);
16}
17 |
|
|
|
|
18 |
/** A method for comparing the areas of two geometric objects */ |
|
||
19 |
public static |
boolean equalArea(GeometricObject object1, |
|
equalArea |
20GeometricObject object2) {
21return object1.getArea() == object2.getArea();
22}
23 |
|
|
|
24 |
/** A method for displaying a geometric object */ |
||
25 |
public static void |
displayGeometricObject(GeometricObject object) |
{ displayGeometricObject |
26System.out.println();
27System.out.println("The area is " + object.getArea());
28System.out.println("The perimeter is " + object.getPerimeter());
29}
30}
The two objects have the same area? false
The area is 78.53981633974483
The perimeter is 31.41592653589793
The area is 14.0
The perimeter is 16.0
The methods getArea() and getPerimeter() defined in the GeometricObject class are overridden in the Circle class and the Rectangle class. The statements (lines 5–6)
GeometricObject geoObject1 = new Circle(5);
GeometricObject geoObject2 = new Rectangle(5, 3);
create a new circle and rectangle and assign them to the variables geoObject1 and geoObject2. These two variables are of the GeometricObject type.
When invoking equalArea(geoObject1, geoObject2) (line 9), the getArea() method defined in the Circle class is used for object1.getArea(), since geoObject1 is a circle, and the getArea() method defined in the Rectangle class is used for object2.getArea(), since geoObject2 is a rectangle.
Similarly, when invoking displayGeometricObject(geoObject1) (line 12), the methods getArea and getPerimeter defined in the Circle class are used, and when invoking displayGeometricObject(geoObject2) (line 15), the methods getArea and getPerimeter defined in the Rectangle class are used. The JVM dynamically determines which of these methods to invoke at runtime, depending on the type of object.