- •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
344Chapter 10 Thinking in Objects
10.1Introduction
The preceding two chapters introduced objects and classes. You learned how to define classes, create objects, and use objects from several classes in the Java API (e.g., Date,
Random, String, StringBuilder, File, Scanner, PrintWriter). This book’s approach is to teach problem solving and fundamental programming techniques before object-oriented programming. This chapter will show how procedural and object-oriented programming differ. You will see the benefits of object-oriented programming and learn to use it effectively.
Our focus here is on class design. We will use several examples to illustrate the advantages of the object-oriented approach. The examples involve designing new classes and using them in applications. We first introduce some language features supporting these examples.
|
10.2 Immutable Objects and Classes |
||||||||
|
Normally, you create an object and allow its contents to be changed later. Occasionally it is desir- |
||||||||
|
able to create an object whose contents cannot be changed, once the object is created. We call |
||||||||
immutable object |
such an object an immutable object and its class an immutable class. The String class, for exam- |
||||||||
immutable class |
ple, is immutable. If you deleted the set method in the Circle class in Listing 8.9, the class |
||||||||
|
would be immutable, because radius is private and cannot be changed without a set method. |
||||||||
|
If a class is immutable, then all its data fields must be private and it cannot contain public |
||||||||
|
set methods for any data fields. A class with all private data fields and no mutators is not nec- |
||||||||
|
essarily immutable. For example, the following Student class has all private data fields and |
||||||||
|
no set methods, but it is not an immutable class. |
||||||||
|
|
|
|||||||
Student class |
1 |
public class Student { |
|
||||||
|
2 |
|
private int id; |
||||||
|
3 |
|
private String name; |
|
|||||
|
4 |
|
private java.util.Date dateCreated; |
|
|||||
|
5 |
|
|
|
|
|
|
|
|
|
6 |
|
public Student(int ssn, String newName) { |
||||||
|
7 |
|
|
id = ssn; |
|||||
|
8 |
|
|
name = newName; |
|
|
|
|
|
|
9 |
|
|
dateCreated = new java.util.Date(); |
|||||
|
10 |
} |
|
|
|
|
|
|
|
|
11 |
|
|
|
|
|
|
|
|
|
12 |
|
public int getId() { |
||||||
|
13 |
|
|
return id; |
|||||
|
14 |
} |
|
|
|
|
|
|
|
|
15 |
|
|
|
|
|
|
|
|
|
16 |
|
public String getName() { |
||||||
|
17 |
|
|
return name; |
|||||
|
18 |
} |
|
|
|
|
|
|
|
|
19 |
|
|
|
|
|
|
|
|
|
20 |
|
public java.util.Date getDateCreated() { |
|
|||||
|
21 |
|
|
return dateCreated; |
|||||
|
22 |
} |
|
|
|
|
|
|
|
|
23 |
} |
|
|
|
|
|
|
|
As shown in the code below, the data field dateCreated is returned using the getDateCreated() method. This is a reference to a Date object. Through this reference, the content for dateCreated can be changed.
public class Test {
public static void main(String[] args) {
Student student = new Student(111223333, "John"); java.util.Date dateCreated = student.getDateCreated();
10.3 The Scope of Variables 345
dateCreated.setTime(200000); // Now dateCreated field is changed!
}
}
For a class to be immutable, it must meet the following requirements:
■all data fields private;
■no mutator methods;
■no accessor method that returns a reference to a data field that is mutable.
10.3The Scope of Variables
Chapter 5, “Methods,” discussed local variables and their scope rules. Local variables are declared and used inside a method locally. This section discusses the scope rules of all the variables in the context of a class.
Instance and static variables in a class are referred to as the class’s variables or data fields. A variable defined inside a method is referred to as a local variable. The scope of a class’s variables is the entire class, regardless of where the variables are declared. A class’s variables and methods can appear in any order in the class, as shown in Figure 10.1(a). The exception is when a data field is initialized based on a reference to another data field. In such cases, the other data field must be declared first, as shown in Figure 10.1(b). For consistency, this book declares data fields at the beginning of the class.
public class Circle { |
|
public class Foo { |
public double findArea() { |
|
private int i; |
return radius * radius * Math.PI; |
|
private int j = i + 1; |
} |
|
} |
private double radius = 1; |
|
|
} |
|
|
|
|
|
(a)variable radius and method findArea() can be declared in any order
(b)i has to be declared before j because j’s initial value is dependent on i.
FIGURE 10.1 Members of a class can be declared in any order, with one exception.
You can declare a class’s variable only once, but you can declare the same variable name in a method many times in different nonnesting blocks.
If a local variable has the same name as a class’s variable, the local variable takes precedence and the class’s variable with the same name is hidden. For example, in the following program, x is defined as an instance variable and as a local variable in the method.
public class Foo {
private int x = 0; // Instance variable private int y = 0;
public Foo() {
}
public void p() {
int x = 1; // Local variable System.out.println("x = " + x); System.out.println("y = " + y);
}
}
What is the printout for f.p(), where f is an instance of Foo? The printout for f.p() is 1 for x and 0 for y. Here is why:
346Chapter 10 Thinking in Objects
■x is declared as a data field with the initial value of 0 in the class, but is also declared in the method p() with an initial value of 1. The latter x is referenced in the
System.out.println statement.
■y is declared outside the method p(), but is accessible inside it.
Tip
To avoid confusion and mistakes, do not use the names of instance or static variables as local variable names, except for method parameters.
10.4 The this Reference
The this keyword is the name of a reference that refers to a calling object itself. One of its hidden data fields common uses is to reference a class’s hidden data fields. For example, a data-field name is often used as the parameter name in a set method for the data field. In this case, the data field is hidden in the set method. You need to reference the hidden data-field name in the method in order to set a new value to it. A hidden static variable can be accessed simply by using the ClassName.StaticVariable reference. A hidden instance variable can be accessed by
using the keyword this, as shown in Figure 10.2(a).
public class Foo { int i = 5;
static double k = 0;
void setI(int i) {
this.i = i ;
}
static void setK(double k) { Foo.k = k;
}
}
(a)
Suppose that f1 and f2 are two objects of Foo.
Invoking f1.setI(10) is to execute this.i = 10, where this refers f1
Invoking f2.setI(45) is to execute this.i = 45, where this refers f2
(b)
FIGURE 10.2 The keyword this refers to the calling object that invokes the method.
The this keyword gives us a way to refer to the object that invokes an instance method within the code of the instance method. The line this.i = i means “assign the value of parameter i to the data field i of the calling object.” The keyword this refers to the object that invokes the instance method setI, as shown in Figure 10.2(b). The line Foo.k = k means that the value in parameter k is assigned to the static data field k of the class, which is shared by all the objects of the class.
call another constructor Another common use of the this keyword is to enable a constructor to invoke another constructor of the same class. For example, you can rewrite the Circle class as follows:
public class Circle { private double radius;
public Circle(double radius) { this.radius = radius;
} |
this must be explicitly used to reference the data |
|
field radius of the object being constructed |
public Circle() { this(1.0);
} this is used to invoke another constructor
public double getArea() {
return this.radius * this.radius * Math.PI; }
}Every instance variable belongs to an instance represented by this, which is normally omitted
10.5 Class Abstraction and Encapsulation 347
The line this(1.0) in the second constructor invokes the first constructor with a double value argument.
Tip
If a class has multiple constructors, it is better to implement them using this(arg-list) as much as possible. In general, a constructor with no or fewer arguments can invoke the constructor with more arguments using this(arg-list). This often simplifies coding and makes the class easier to read and to maintain.
Note
Java requires that the this(arg-list) statement appear first in the constructor before any other statements.
10.5 Class Abstraction and Encapsulation
In Chapter 5, “Methods,” you learned about method abstraction and used it in program development. Java provides many levels of abstraction. Class abstraction is the separation of class implementation from the use of a class. The creator of a class describes it and lets the user know how it can be used. The collection of methods and fields that are accessible from outside the class, together with the description of how these members are expected to behave, serves as the class’s contract. As shown in Figure 10.3, the user of the class does not need to know how the class is implemented. The details of implementation are encapsulated and hidden from the user. This is known as class encapsulation. For example, you can create a Circle object and find the area of the circle without knowing how the area is computed.
Class implementation |
|
|
|
Class Contract |
|
|
|
Clients use the |
is like a black box |
|
|
|
|
||||
|
(signatures of |
|
|
|
||||
hidden from the clients |
Class |
|
|
|
class through the |
|||
public methods and |
|
|
|
|||||
|
|
|
|
|
|
|
contract of the class |
|
|
|
|
|
public constants) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class abstraction
class encapsulation
FIGURE 10.3 Class abstraction separates class implementation from the use of the class.
Class abstraction and encapsulation are two sides of the same coin. Many real-life examples illustrate the concept of class abstraction. Consider, for instance, building a computer system. Your personal computer has many components—a CPU, memory, disk, motherboard, fan, and so on. Each component can be viewed as an object that has properties and methods. To get the components to work together, you need know only how each component is used and how it interacts with the others. You don’t need to know how the components work internally. The internal implementation is encapsulated and hidden from you. You can build a computer without knowing how a component is implemented.
The computer-system analogy precisely mirrors the object-oriented approach. Each component can be viewed as an object of the class for the component. For example, you might have a class that models all kinds of fans for use in a computer, with properties such as fan size and speed and methods such as start and stop. A specific fan is an instance of this class with specific property values.
As another example, consider getting a loan. A specific loan can be viewed as an object of a Loan class. Interest rate, loan amount, and loan period are its data properties, and computing monthly payment and total payment are its methods. When you buy a car, a loan object is created by instantiating the class with your loan interest rate, loan amount, and loan period. You can then use the methods to find the monthly payment and total payment of your loan. As a user of the Loan class, you don’t need to know how these methods are implemented.
Listing 2.8, ComputeLoan.java, presented a program for computing loan payments. The program cannot be reused in other programs. One way to fix this problem is to define static methods for computing monthly payment and total payment. However, this solution has limitations. Suppose you wish to associate a date with the loan. The ideal way is to create an
Video Note
The Loan class
348 Chapter 10 Thinking in Objects
|
|
|
-annualInterestRate: double |
|
The annual interest rate of the loan (default: 2.5). |
-numberOfYears: int |
|
The number of years for the loan (default: 1). |
-loanAmount: double |
|
The loan amount (default: 1000). |
-loanDate: java.util.Date |
|
The date this loan was created. |
|
|
Constructs a default Loan object. |
|
|
|
|
|
|
|
|
Constructs a loan with specified interest rate, years, |
|
|
and loan amount. |
|
|
Returns the annual interest rate of this loan. |
|
|
Returns the number of the years of this loan. |
|
|
Returns the amount of this loan. |
|
|
Returns the date of the creation of this loan. |
|
|
Sets a new annual interest rate to this loan. |
|
|
Sets a new number of years to this loan. |
|
|
Sets a new amount for this loan. |
|
|
Returns the monthly payment of this loan. |
|
|
Returns the total payment of this loan. |
|
|
|
FIGURE 10.4 The Loan class models the properties and behaviors of loans.
object that ties the properties for loan information and date together. Figure 10.4 shows the UML class diagram for the Loan class.
The UML diagram in Figure 10.4 serves as the contract for the Loan class. Throughout this book, you will play the roles of both class user and class developer. The user can use the class without knowing how the class is implemented. Assume that the Loan class is available. We begin by writing a test program that uses the Loan class (Listing 10.1).
LISTING 10.1 TestLoanClass.java
1 import java.util.Scanner;
2
3 public class TestLoanClass {
4/** Main method */
5 public static void main(String[] args) {
6// Create a Scanner
7 Scanner input = new Scanner(System.in);
8
9// Enter yearly interest rate
10System.out.print(
11"Enter yearly interest rate, for example, 8.25: ");
12double annualInterestRate = input.nextDouble();
13
14// Enter number of years
15System.out.print("Enter number of years as an integer: ");
16int numberOfYears = input.nextInt();
17
18// Enter loan amount
19System.out.print("Enter loan amount, for example, 120000.95: ");
10.5 Class Abstraction and Encapsulation 349
20 double loanAmount = input.nextDouble();
21
22// Create a Loan object
23Loan loan =
24new Loan(annualInterestRate, numberOfYears, loanAmount);
25
26// Display loan date, monthly payment, and total payment
27System.out.printf("The loan was created on %s\n" +
28"The monthly payment is %.2f\nThe total payment is %.2f\n",
29loan.getLoanDate().toString(), loan.getMonthlyPayment(),
30loan.getTotalPayment());
31}
32}
Enter yearly interest rate, for example, 8.25: 2.5
Enter number of years as an integer: 5
Enter loan amount, for example, 120000.95: 1000 The loan was created on Sat Jun 10 21:12:50 EDT 2006 The monthly payment is 17.74
The total payment is 1064.84
create Loan object
invoke instance method invoke instance method
The main method reads interest rate, payment period (in years), and loan amount; creates a Loan object; and then obtains the monthly payment (line 29) and total payment (line 30) using the instance methods in the Loan class.
The Loan class can be implemented as in Listing 10.2.
LISTING 10.2 Loan.java
1 public class Loan {
2 private double annualInterestRate;
3 private int numberOfYears;
4private double loanAmount;
5 private java.util.Date loanDate;
6
7/** Default constructor */
8 public Loan() { |
no-arg constructor |
9this(2.5, 1, 1000);
10 |
} |
11 |
|
12/** Construct a loan with specified annual interest rate,
13number of years, and loan amount
14*/
15 |
public Loan(double annualInterestRate, int numberOfYears, |
constructor |
16double loanAmount) {
17this.annualInterestRate = annualInterestRate;
18this.numberOfYears = numberOfYears;
19this.loanAmount = loanAmount;
20loanDate = new java.util.Date();
21}
22
23/** Return annualInterestRate */
24public double getAnnualInterestRate() {
25return annualInterestRate;
26}
350 Chapter 10 Thinking in Objects
27
28/** Set a new annualInterestRate */
29public void setAnnualInterestRate(double annualInterestRate) {
30this.annualInterestRate = annualInterestRate;
31}
32
33/** Return numberOfYears */
34public int getNumberOfYears() {
35return numberOfYears;
36}
37
38/** Set a new numberOfYears */
39public void setNumberOfYears(int numberOfYears) {
40this.numberOfYears = numberOfYears;
41}
42
43/** Return loanAmount */
44public double getLoanAmount() {
45return loanAmount;
46}
47
48/** Set a newloanAmount */
49public void setLoanAmount(double loanAmount) {
50this.loanAmount = loanAmount;
51}
52
53/** Find monthly payment */
54public double getMonthlyPayment() {
55double monthlyInterestRate = annualInterestRate / 1200;
56double monthlyPayment = loanAmount * monthlyInterestRate / (1 -
57(Math.pow(1 / (1 + monthlyInterestRate), numberOfYears * 12)));
58return monthlyPayment;
59}
60
61/** Find total payment */
62public double getTotalPayment() {
63double totalPayment = getMonthlyPayment() * numberOfYears * 12;
64return totalPayment;
65}
66
67/** Return loan date */
68public java.util.Date getLoanDate() {
69return loanDate;
70}
71}
From a class developer’s perspective, a class is designed for use by many different customers. In order to be useful in a wide range of applications, a class should provide a variety of ways for customization through constructors, properties, and methods.
The Loan class contains two constructors, four get methods, three set methods, and the methods for finding monthly payment and total payment. You can construct a Loan object by using the no-arg constructor or the one with three parameters: annual interest rate, number of years, and loan amount. When a loan object is created, its date is stored in the loanDate field. The getLoanDate method returns the date. The three get methods, getAnnualInterest, getNumberOfYears, and getLoanAmount, return annual interest rate, payment years, and loan amount, respectively. All the data properties and methods in this class are tied to a specific instance of the Loan class. Therefore, they are instance variables or methods.