- •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
10.6 Object-Oriented Thinking 351
Important Pedagogical Tip
The UML diagram for the Loan class is shown in Figure 10.4. Students should begin by writing a test program that uses the Loan class even though they don’t know how the Loan class is implemented. This has three benefits:
■It demonstrates that developing a class and using a class are two separate tasks.
■It enables you to skip the complex implementation of certain classes without interrupting the sequence of the book.
■It is easier to learn how to implement a class if you are familiar with the class through using it.
For all the examples from now on, you may first create an object from the class and try to use its methods and then turn your attention to its implementation.
10.6 Object-Oriented Thinking
Chapters 1–7 introduced fundamental programming techniques for problem solving using loops, methods, and arrays. The study of these techniques lays a solid foundation for objectoriented programming. Classes provide more flexibility and modularity for building reusable software. This section improves the solution for a problem introduced in Chapter 3 using the object-oriented approach. From the improvements, you will gain insight on the differences between procedural and object-oriented programming and see the benefits of developing reusable code using objects and classes.
Listing 3.5, ComputeBMI.java, presented a program for computing body mass index. The code cannot be reused in other programs. To make it reusable, define a static method to compute body mass index as follows:
public static double getBMI(double weight, double height)
This method is useful for computing body mass index for a specified weight and height. However, it has limitations. Suppose you need to associate the weight and height with a person’s name and birth date. You may declare separate variables to store these values. But these values are not tightly coupled. The ideal way to couple them is to create an object that contains them. Since these values are tied to individual objects, they should be stored in instance data fields. You can define a class named BMI, as shown in Figure 10.5.
The get methods for these data fields
are provided in the class, but omitted in the
UML diagram for brevity.
BMI
-name: String -age: int -weight: double -height: double
+BMI(name: String, age: int, weight: double, height: double)
+BMI(name: String, weight: double, height: double)
+getBMI(): double +getStatus(): String
Video Note
The BMI class
FIGURE 10.5 The BMI class encapsulates BMI information.
352 Chapter 10 |
Thinking in Objects |
|||||||||||||
|
|
Assume that the BMI class is available. Listing 10.3 gives a test program that uses this |
||||||||||||
|
class. |
|||||||||||||
|
LISTING 10.3 UseBMIClass.java |
|||||||||||||
|
1 |
public class UseBMIClass { |
||||||||||||
|
2 |
public static void main(String[] args) { |
||||||||||||
create an object |
3 |
|
BMI bmi1 = new BMI("John Doe", 18, 145, 70); |
|
||||||||||
invoke instance method |
4 |
|
System.out.println("The BMI for " + |
bmi1.getName() |
+ " is " |
|||||||||
|
5 |
|
+ |
bmi1.getBMI() |
+ " " + |
bmi1.getStatus() |
); |
|
||||||
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
create an object |
7 |
|
BMI bmi2 = new BMI("Peter King", 215, 70); |
|
|
|
||||||||
invoke instance method |
8 |
|
System.out.println("The BMI for " + |
bmi2.getName() |
+ " is " |
|||||||||
|
9 |
+ |
bmi2.getBMI() |
+ " " + |
bmi2.getStatus() |
); |
|
|
||||||
|
10 |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
} |
|
|
|
|
|
|
|
|
|
|
|
|
The BMI for John Doe is 20.81 normal weight
The BMI for Peter King is 30.85 seriously overweight
Line 3 creates an object bmi1 for John Doe and line 7 creates an object bmi2 for Peter King. You can use the instance methods getName(), getBMI(), and getStatus() to return the BMI information in a BMI object.
The BMI class can be implemented as in Listing 10.4.
LISTING 10.4 BMI.java
1 public class BMI {
2 private String name;
|
3 |
private int age; |
||||
|
4 |
private double weight; // in pounds |
||||
|
5 |
private double height; // in inches |
||||
|
6 |
public static final double KILOGRAMS_PER_POUND = 0.45359237; |
||||
|
7 |
public static final double METERS_PER_INCH = 0.0254; |
||||
|
8 |
|
|
|
|
|
constructor |
9 |
public BMI(String name, int age, double weight, double height) { |
||||
|
10 |
|
this.name = name; |
|||
|
11 |
|
this.age = age; |
|||
|
12 |
|
this.weight = weight; |
|||
|
13 |
|
this.height = height; |
|||
|
14 |
} |
|
|
|
|
|
15 |
|
|
|
|
|
constructor |
16 |
public BMI(String name, double weight, double height) { |
||||
|
17 |
|
this(name, 20, weight, height); |
|
||
|
18 |
} |
|
|
|
|
|
19 |
|
|
|
|
|
getBMI |
20 |
public double getBMI() { |
|
|
||
|
21 |
|
double bmi = weight * KILOGRAMS_PER_POUND / |
|||
|
22 |
|
((height * METERS_PER_INCH) * (height * METERS_PER_INCH)); |
|||
|
23 |
|
return Math.round(bmi * 100) / 100.0; |
|||
|
24 |
} |
|
|
|
|
|
25 |
|
|
|
|
|
getStatus |
26 |
public String getStatus() { |
|
|
||
|
27 |
|
double bmi = getBMI(); |
|||
|
28 |
|
if (bmi < 16) |
|||
|
29 |
|
return "seriously underweight"; |
|||
|
30 |
|
else if (bmi < 18) |
10.7 Object Composition 353
31return "underweight";
32else if (bmi < 24)
33return "normal weight";
34else if (bmi < 29)
35return "overweight";
36else if (bmi < 35)
37return "seriously overweight";
38else
39return "gravely overweight";
40}
41
42public String getName() {
43return name;
44}
45
46public int getAge() {
47return age;
48}
49
50public double getWeight() {
51return weight;
52}
53
54public double getHeight() {
55return height;
56}
57}
The mathematic formula for computing the BMI using weight and height is given in §3.10. The instance method getBMI() returns the BMI. Since the weight and height are instance data fields in the object, the getBMI() method can use these properties to compute the BMI for the object.
The instance method getStatus() returns a string that interprets the BMI. The interpretation is also given in §3.10.
This example demonstrates the advantages of the object-oriented paradigm over the procedural paradigm. The procedural paradigm focuses on designing methods. The objectoriented paradigm couples data and methods together into objects. Software design using the object-oriented paradigm focuses on objects and operations on objects. The object-oriented approach combines the power of the procedural paradigm with an added dimension that integrates data with operations into objects.
In procedural programming, data and operations on the data are separate, and this methodology requires sending data to methods. Object-oriented programming places data and the operations that pertain to them in an object. This approach solves many of the problems inherent in procedural programming. The object-oriented programming approach organizes programs in a way that mirrors the real world, in which all objects are associated with both attributes and activities. Using objects improves software reusability and makes programs easier to develop and easier to maintain. Programming in Java involves thinking in terms of objects; a Java program can be viewed as a collection of cooperating objects.
Procedural vs. ObjectOriented Paradigms
10.7 Object Composition
An object can contain another object. The relationship between the two is called composition. In Listing 10.4, you defined the BMI class to contain a String data field. The relationship between BMI and String is composition.
Composition is actually a special case of the aggregation relationship. Aggregation models has-a relationships and represents an ownership relationship between two objects. The owner
354 Chapter 10 Thinking in Objects
object is called an aggregating object and its class an aggregating class. The subject object is called an aggregated object and its class an aggregated class.
An object may be owned by several other aggregating objects. If an object is exclusively composition owned by an aggregating object, the relationship between them is referred to as composition.
For example, “a student has a name” is a composition relationship between the Student class and the Name class, whereas “a student has an address” is an aggregation relationship between the Student class and the Address class, since an address may be shared by several students. In UML, a filled diamond is attached to an aggregating class (e.g., Student) to denote the composition relationship with an aggregated class (e.g., Name), and an empty diamond is attached to an aggregating class (e.g., Student) to denote the aggregation relationship with an aggregated class (e.g., Address), as shown in Figure 10.6.
|
Composition |
Aggregation |
|
1 |
1 |
1 |
1..3 |
Name |
Student |
|
Address |
FIGURE 10.6 A student has a name and an address.
multiplicity |
Each class involved in a relationship may specify a multiplicity. A multiplicity could be a |
||||
|
number or an interval that specifies how many objects of the class are involved in the rela- |
||||
|
tionship. The character * means an unlimited number of objects, and the interval m..n means |
||||
|
that the number of objects should be between m and n, inclusive. In Figure 10.6, each student |
||||
|
has only one address, and each address may be shared by up to 3 students. Each student has |
||||
|
one name, and a name is unique for each student. |
|
|
||
|
An aggregation relationship is usually represented as a data field in the aggregating class. |
||||
|
For example, the relationship in Figure 10.6 can be represented as follows: |
||||
|
|
|
|
|
|
|
public class Name { |
|
public class Student { |
|
public class Address { |
|
... |
|
private Name name; |
|
... |
|
} |
|
private Address address; |
|
} |
|
|
|
... |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Aggregated class |
|
Aggregating class |
|
Aggregated class |
Aggregation may exist between objects of the same class. For example, a person may have a supervisor. This is illustrated in Figure 10.7.
Person |
1 |
|
|
1 |
Supervisor |
FIGURE 10.7 A person may have a supervisor.
In the relationship “a person has a supervisor,” as shown in Figure 10.7, a supervisor can be represented as a data field in the Person class, as follows:
public class Person { |
|
// The type for the |
data is the class itself |