- •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
278 Chapter 8 |
Objects and Classes |
||
|
|
|
radio button, and combo box (lines 35–43). The program then creates a frame and adds the |
|
|
|
panel to the frame (line 45). The frame is displayed in line 51. |
|
|
|
8.7 Static Variables, Constants, and Methods |
instance variable |
The data field radius in the circle class in Listing 8.1 is known as an instance variable. An |
||
|
|
|
instance variable is tied to a specific instance of the class; it is not shared among objects of the |
|
|
|
same class. For example, suppose that you create the following objects: |
|
|
|
|
Video Note static vs. instance
static variable
static method
Circle circle1 = new Circle();
Circle circle2 = new Circle(5);
The radius in circle1 is independent of the radius in circle2 and is stored in a different memory location. Changes made to circle1’s radius do not affect circle2’s radius, and vice versa.
If you want all the instances of a class to share data, use static variables, also known as class variables. Static variables store values for the variables in a common memory location. Because of this common location, if one object changes the value of a static variable, all objects of the same class are affected. Java supports static methods as well as static variables. Static methods can be called without creating an instance of the class.
Let us modify the Circle class by adding a static variable numberOfObjects to count the number of circle objects created. When the first object of this class is created, numberOfObjects is 1. When the second object is created, numberOfObjects becomes 2. The UML of the new circle class is shown in Figure 8.12. The Circle class defines the instance variable radius and the static variable numberOfObjects, the instance methods getRadius, setRadius, and getArea, and the static method getNumberOfObjects. (Note that static variables and methods are underlined in the UML class diagram.)
UML Notation: |
|
|
|
|
|
|
|
|
|
|
|
||
underline: static variables or methods |
instantiate |
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
circle1: Circle |
|
Memory |
|
After two Circle |
||||||
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
radius = 1 |
|
|
|
|
1 |
|
radius |
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
numberOfObjects = 2 |
|
|
|
|
|
|
Objects were created, |
||
Circle |
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
numberOfObjects |
radius: double |
|
|
|
|
|
|
|
|
|
|
|
|
is 2. |
numberOfObjects: int |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
|
numberOfObjects |
||
|
|
|
|
|
|
|
|
|
|
|
|||
getNumberOfObjects(): int |
|
|
instantiate |
|
|
|
|
|
|
|
|
|
|
getArea(): double |
|
|
|
|
|
|
|
|
|
|
|
||
|
|
circle2: Circle |
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
radius = 5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
radius |
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
numberOfObjects = 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FIGURE 8.12 Instance variables belong to the instances and have memory storage independent of one another. Static variables are shared by all the instances of the same class.
To declare a static variable or define a static method, put the modifier static in the variable or method declaration. The static variable numberOfObjects and the static method getNumberOfObjects() can be declared as follows:
declare static variable |
static |
int numberOfObjects; |
|
|
|
define static method |
static |
int getNumberObjects() { |
|
return numberOfObjects; |
|
|
} |
|
Constants in a class are shared by all objects of the class. Thus, constants should be declared final static. For example, the constant PI in the Math class is defined as:
declare constant |
final static double PI = 3.14159265358979323846; |
8.7 Static Variables, Constants, and Methods 279
The new circle class, named Circle2, is declared in Listing 8.7:
LISTING 8.7 Circle2.java
1 public class Circle2 {
2 /** The radius of the circle */
3 double radius;
4
5/** The number of objects created */
6 |
static int numberOfObjects = 0; |
|
static variable |
7 |
|
|
|
8 |
/** Construct a circle with radius 1 */ |
|
9Circle2() {
10 |
|
radius = 1.0; |
|
11 |
|
numberOfObjects++; |
increase by 1 |
12 |
} |
|
|
13 |
|
|
|
14/** Construct a circle with a specified radius */
15Circle2(double newRadius) {
16radius = newRadius;
17 |
|
numberOfObjects++; |
|
increase by 1 |
18 |
} |
|
|
|
19 |
|
|
|
|
20 |
/** Return numberOfObjects */ |
|
||
21 |
static int getNumberOfObjects() { |
static method |
22return numberOfObjects;
23}
24
25/** Return the area of this circle */
26double getArea() {
27return radius * radius * Math.PI;
28}
29}
Method getNumberOfObjects() in Circle2 is a static method. Other examples of static methods are showMessageDialog and showInputDialog in the JOptionPane class and all the methods in the Math class. The main method is static, too.
Instance methods (e.g., getArea()) and instance data (e.g., radius) belong to instances and can be used only after the instances are created. They are accessed via a reference variable. Static methods (e.g., getNumberOfObjects()) and static data (e.g., numberOfObjects) can be accessed from a reference variable or from their class name.
The program in Listing 8.8 demonstrates how to use instance and static variables and methods and illustrates the effects of using them.
LISTING 8.8 TestCircle2.java
1 public class TestCircle2 {
2/** Main method */
3public static void main(String[] args) {
4System.out.println("Before creating objects");
5System.out.println("The number of Circle objects is " +
6 |
Circle2.numberOfObjects); |
static variable |
7 |
|
|
8// Create c1
9 Circle2 c1 = new Circle2();
10
11// Display c1 BEFORE c2 is created
12System.out.println("\nAfter creating c1");
13 |
System.out.println("c1: radius (" |
+ c1.radius + |
instance variable |
14 |
") and number of Circle objects |
(" + |
|
280 Chapter 8 |
Objects and Classes |
|||||||
|
|
|
|
|||||
static variable |
15 |
|
c1.numberOfObjects |
+ ")"); |
||||
|
16 |
|
|
|
|
|
|
|
|
17 |
// Create c2 |
||||||
|
18 |
Circle2 c2 = new Circle2(5); |
|
|||||
|
19 |
|
|
|
|
|
|
|
|
20 |
// Modify c1 |
||||||
instance variable |
21 |
c1.radius = 9; |
|
|
|
|||
|
22 |
|
|
|
|
|
|
|
|
23 |
// Display c1 and c2 AFTER c2 was created |
||||||
|
24 |
System.out.println("\nAfter creating c2 and modifying c1"); |
||||||
|
25 |
System.out.println("c1: radius (" + c1.radius + |
||||||
|
26 |
|
") and number of Circle objects (" + |
|||||
static variable |
27 |
|
c1.numberOfObjects |
+ ")"); |
|
|||
|
28 |
System.out.println("c2: radius (" + c2.radius + |
||||||
|
29 |
|
") and number of Circle objects (" + |
|||||
static variable |
30 |
|
c2.numberOfObjects |
+ ")"); |
|
31}
32}
Before creating objects
The number of Circle objects is 0
After creating c1
c1: radius (1.0) and number of Circle objects (1)
After creating c2 and modifying c1
c1: radius (9.0) and number of Circle objects (2) c2: radius (5.0) and number of Circle objects (2)
When you compile TestCircle2.java, the Java compiler automatically compiles Circle2.java if it has not been compiled since the last change.
Static variables and methods can be accessed without creating objects. Line 6 displays the number of objects, which is 0, since no objects have been created.
The main method creates two circles, c1 and c2 (lines 9, 18). The instance variable radius in c1 is modified to become 9 (line 21). This change does not affect the instance variable radius in c2, since these two instance variables are independent. The static variable numberOfObjects becomes 1 after c1 is created (line 9), and it becomes 2 after c2 is created (line 18).
|
Note that PI is a constant defined in Math, and Math.PI references the constant. |
|
c.numberOfObjects could be replaced by Circle2.numberOfObjects. This improves |
|
readability, because the reader can easily recognize the static variable. You can also replace |
|
Circle2.numberOfObjects by Circle2.getNumberOfObjects(). |
|
Tip |
use class name |
Use ClassName.methodName(arguments) to invoke a static method and ClassName.- |
|
staticVariable to access a static variable. This improves readability, because the user can |
|
easily recognize the static method and data in the class. |
Static variables and methods can be used from instance or static methods in the class. However, instance variables and methods can be used only from instance methods, not from static methods, since static variables and methods don’t belong to a particular object. Thus the code given below is wrong.
1 public class Foo {
2int i = 5;
3 static int k = 2;
4
5public static void main(String[] args) {
6 int j = i; // Wrong because i is an instance variable 7 m1(); // Wrong because m1() is an instance method
8.7 Static Variables, Constants, and Methods 281
8 |
} |
9 |
|
10public void m1() {
11// Correct since instance and static variables and methods
12// can be used in an instance method
13i = i + k + m2(i, k);
14}
15
16public static int m2(int i, int j) {
17return (int)(Math.pow(i, j));
18}
19}
Note that if you replace the code in lines 5–8 with the following new code, the program is fine, because the instance data field i and method m1 are now accessed from an object foo (lines 6–7):
1 public class Foo {
2int i = 5;
3 static int k = 2;
4
5 public static void main(String[] args) {
6Foo foo = new Foo();
7int j = foo.i; // OK, foo.i accesses the object's instance variable
8 |
|
foo.m1(); |
// OK. Foo.m1() invokes object's instance method |
9 |
} |
|
|
10
11public void m1() {
12i = i + k + m2(i, k);
13}
14 |
|
15 |
public static int m2(int i, int j) { |
16 |
return (int)(Math.pow(i, j)); |
17 |
} |
18 |
} |
Design Guide
How do you decide whether a variable or method should be an instance one or a static one? A vari- |
instance or static? |
able or method that is dependent on a specific instance of the class should be an instance variable or |
|
method. A variable or method that is not dependent on a specific instance of the class should be a |
|
static variable or method. For example, every circle has its own radius. Radius is dependent on a spe- |
|
cific circle. Therefore, radius is an instance variable of the Circle class. Since the getArea |
|
method is dependent on a specific circle, it is an instance method. None of the methods in the Math |
|
class, such as random, pow, sin, and cos, is dependent on a specific instance. Therefore, these |
|
methods are static methods. The main method is static and can be invoked directly from a class. |
|
Caution
It is a common design error to define an instance method that should have been defined static. |
common design error |
For example, the method factorial(int n) should be defined static, as shown below, |
|
because it is independent of any specific instance. |
|
public class Test {
public int factorial(int n) { int result = 1;
for (int i = 1; i <= n; i++) result *= i;
return result;
}
}
public class Test {
public static int factorial(int n) int result = 1;
for (int i = 1; i <= n; i++) result *= i;
return result;
}
}
(a) Wrong design |
(b) Correct design |