Chapter 8 – Designing Classes
Discovering Classes
-
A class represents a single concept from the problem domain
-
Name for a class should be a noun that describes concept
-
Concepts from mathematics:
Point
Rectangle
Ellipse
-
Concepts from real life:
BankAccount
CashRegister
Self Check 8.1
What is the rule of thumb for finding classes?
- Answer:
Look for nouns in the problem description.
Self Check 8.2
Your job is to write a program that plays chess. Might
ChessBoard be an
appropriate class? How about
MovePiece?
- Answer:
Yes (ChessBoard) and no (MovePiece).
Designing Good Methods - Cohesion
-
A class should represent a single concept
-
The public interface of a class is cohesive if all of its features are related
to the concept that the class represents
- The members of a cohesive team have a common goal.

Designing Good Methods - Cohesion
- This class lacks cohesion.
public class CashRegister
{
public static final double QUARTER_VALUE = 0.25;
public static final double DIME_VALUE = 0.1;
public static final double NICKEL_VALUE = 0.05;
. . .
public void receivePayment(int dollars, int quarters,
int dimes, int nickels, int pennies)
. . .
}
- It contains two concepts
- A cash register that holds coins and computes their total
- The values of individual coins.
Designing Good Methods - Cohesion
-
Solution: Make two classes:
public class Coin
{
public Coin(double aValue, String aName) { . . . }
public double getValue() { . . . }
. . .
}
}
public class CashRegister
{
. . .
public void receivePayment(int coinCount, Coin coinType)
{
payment = payment + coinCount * coinType.getValue();
}
. . .
}
- Now CashRegister class can handle any type of coin
Minimizing Dependencies
-
A class depends on another class if its
methods use that
class in any way.
- CashRegister depends on Coin
-
UML: Unified Modeling Language
-
Notation for object-oriented analysis and design
- UML class diagram showing dependency relationship between the CashRegister and Coin Classes

- The Coin class does not depend on the CashRegister class
Separating Accessors and Mutators
- A mutator method changes the state of an object
- An accessor method asks an object to compute a result, without changing the state
- An immutable class has no
mutator methods.
- String is an immutable class
- No method in the String class can modify the contents of a string
- References to objects of an immutable class can be safely shared.
Separating Accessors and Mutators
- In a mutable class, separate accessors and mutators
- A method that returns a value should not be a mutator
- In general, all mutators of your class should have return type void.
- Sometimes a mutator method can return an informational value
- ArrayList remove method returns true if the removal was successful
- To check the temperature of the water in the bottle, you could take a sip, but that would be the equivalent of a mutator method.
Self Check 8.3
Why is the
CashRegister class from Chapter 4 not cohesive?
- Answer:
Some of its features deal with payments, others with coin values.
Self Check 8.4
Why does the
Coin class not depend on the
CashRegister class?
- Answer:
None of the coin operations require the CashRegister class.
Self Check 8.5
Why is it a good idea to minimize dependencies between classes?
- Answer:
If a class doesn't depend on another, it is not affected by interface changes in
the other class.
Self Check 8.6
Is the
substring method of the
String class an accessor or a
mutator?
- Answer:
It is an accessor – calling substring doesn't modify the string
on which the method is invoked. In fact, all methods of the String
class are accessors.
Self Check 8.7
Is the
Rectangle class immutable?
- Answer:
No – translate is a mutator.
Self Check 8.8
If
a refers to a bank account, then the call
a.deposit(100)
modifies the bank account object. Is that a side effect?
- Answer:
It is a side effect; this kind of side effect is common in object-oriented programming.
Self Check 8.9
Consider the Student class of Chapter 7. Suppose we add a method
void read(Scanner in)
{
while (in.hasNextDouble())
addScore(in.nextDouble());
}
Does this method have a side effect other than mutating the data set?
- Answer:
Yes – the method affects the state of the Scanner argument.
Consistency
While it is possible to eat
with mismatched silverware,
consistency is more pleasant.
Problem Solving: Patterns for Object Data - Keeping a Total
All classes that manage a total follow the same basic pattern
- Keep an instance variable that represents the current total
private double purchase;
- Provide these methods as necessary
- A method to increase the total by a given amount
public void recordPurchase(double amount)
{
purchase = purchase + amount;
}
- A method that reduces or clears the total
public void clear()
{
purchase = 0;
}
- A method that yields the current total
public double getAmountDue()
{
return purchase;
}
Problem Solving: Patterns for Object Data - Counting Events
A counter that
counts events
is incremented
in methods that
correspond to
the events.
Problem Solving: Patterns for Object Data - Collecting Values
An object can collect
other objects in an
array or array list.
Problem Solving: Patterns for Object Data - Collecting Values
Problem Solving: Patterns for Object Data - Managing Properties of an Object
- A property is a value of an object that an object user can set and retrieve
- Provide an instance variable to store the property’s value and methods to get and set it.
public class Student
{
private String name;
. . .
public String getName() { return name; }
public void setName(String newName) { name = newName; }
...
}
- It is common to add error checking to the setter method
public void setName(String newName)
{
if (newName.length() > 0) { name = newName; }
}
- Some properties should not change after they have been set in the constructor
Problem Solving: Patterns for Object Data - Modeling Objects with Distinct States
Problem Solving: Patterns for Object Data - Modeling Objects with Distinct States
Problem Solving: Patterns for Object Data - Describing the Position of an Object
- To model a moving
object:
- You need to
store and update
its position.
- You may also need to store its orientation or velocity
- If the object moves along a line, you can represent the position as a distance from a
fixed point
private double distanceFromTerminus;
- If the object moves in a grid, remember its current location and direction in the grid
private int row;
private int column;
private int direction; // 0 = North, 1 = East, 2 = South, 3 = West
- A bug in a grid needs to store its row,
column, and direction.

Problem Solving: Patterns for Object Data - Describing the Position of an Object
- There will be methods that update the position
- You may be told how much the object moves
public void move(double distanceMoved)
{
distanceFromTerminus = distanceFromTerminus + distanceMoved;
}
- If the movement happens in a grid, you need to update the row or column, depending on the current orientation.
public void moveOneUnit()
{
if (direction == NORTH) { row--; }
else if (direction == EAST) { column++; }
else if (direction == SOUTH) { row++; }
else if (direction == WEST) { column––; }
}
- Your program will simulate the actual movement in some way
- Locate the methods that move the object, and update the positions according to the rules of the simulation
Self Check 8.10
Suppose we want to count the number of transactions in a bank account in a
statement period, and we add a counter to the BankAccount class:
public class BankAccount
{
private int transactionCount;
...
}
In which methods does this counter need to be updated?
- Answer: It needs to be incremented in the deposit and
withdraw methods. There also needs to be some
method to reset it after the end of a statement
period.
Self Check 8.11
In How To 3.1, the CashRegister class does not have a getTotalPurchase method.
Instead, you have to call receivePayment and then giveChange. Which recommendation
of Section 8.2.4 does this design violate? What is a better alternative?
- Answer: The giveChange method is a mutator that returns
a value that cannot be determined any other
way. Here is a better design. The receivePayment
method could decrease the purchase instance
variable. Then the program user would call
receivePayment, determine the change by calling
getAmountDue, and call the clear method to reset
the cash register for the next sale.
Self Check 8.12
In the example in Section 8.3.3, why is the add method required? That is, why can’t the user of a Question object just call the add method of the ArrayList<String> class?
-
Answer:
The ArrayList<String> instance variable is private, and the class users cannot acccess it.
Self Check 8.13
Suppose we want to enhance the CashRegister class in How To 3.1 to track the prices of all purchased items for printing a receipt. Which instance variable should you provide? Which methods should you modify?
-
Answer:
You need to supply an instance variable
that can hold the prices for all purchased
items. This could be an ArrayList<Double> or
ArrayList<String>, or it could simply be a String
to which you append lines. The instance variable
needs to be updated in the recordPurchase
method. You also need a method that returns
the receipt.
Self Check 8.14
Consider an Employee class with properties for tax ID number and salary. Which
of these properties should have only a getter method, and which should have
getter and setter methods?
-
Answer:
The tax ID of an employee does not change,
and no setter method should be supplied. The
salary of an employee can change, and both
getter and setter methods should be supplied.
Self Check 8.15
Suppose the setName method in Section 8.3.4 is changed so that it returns true if
the new name is set, false if not. Is this a good idea?
-
Answer:
Section 8.2.3 suggests that a setter should
return void, or perhaps a convenience value
that the user can also determine in some other
way. In this situation, the caller could check
whether newName is blank, so the change is fine.
Self Check 8.16
Look at the direction instance variable in the bug example in Section 8.3.6. This
is an example of which pattern?
-
Answer: It is an example of the “state pattern”
described in Section 8.3.5. The direction is a
state that changes when the bug turns, and it
affects how the bug moves.
Static Variables and Methods - Variables
Static Variables and Methods
Static Variables and Methods

A Static Variable and Instance Variables
Static Variables and Methods - Methods
- Sometimes a class defines methods that are not invoked on an object
- Example: sqrt method of Math class
- if x is a number, then the call x.sqrt() is not legal
- Math class provides a static method: invoked as Math.sqrt(x)
- No object
of the Math class is constructed.
- The Math qualifier simply tells the compiler where to
find the sqrt method.
Static Variables and Methods
- You can define your own static methods
public class Financial
{
/**
Computes a percentage of an amount.
@param percentage the percentage to apply
@param amount the amount to which the percentage is applied
@return the requested percentage of the amount
*/
public static double percentOf(double percentage, double amount)
{
return (percentage / 100) * amount;
}
}
- When calling such a method, supply the name of the class containing it
double tax = Financial.percentOf(taxRate, total);
- The main method is always static.
- When the program starts, there aren’t any objects.
- Therefore, the first method of a program must be a static method.
- Programming Tip: Minimize the Use of Static Methods
Self Check 8.17
Name two static variables of the
System class.
- Answer:
System.in and System.out.
Self Check 8.18
Name a static constant of the Math class
Self Check 8.19
The following method computes the average of an array of numbers:
public static double average(double[] values)
Why should it not be defined as an instance method?
-
Answer:
The method needs no data of any object. The only required input is the values argument.
Self Check 8.20
Harry tells you that he has found a great way to avoid those pesky objects: Put
all code into a single class and declare all methods and variables
static.
Then
main can call the other static methods, and all of them can access
the static variables. Will Harry's plan work? Is it a good idea?
- Answer:
Yes, it works. Static methods can access static variables of the same class. But it
is a terrible idea. As your programming tasks get more complex, you will want to
use objects and classes to organize your programs.
Packages
-
Package: Set of related classes
- Important packages in the Java library:
| Package |
Purpose |
Sample Class |
| java.lang |
Language support |
Math |
| java.util |
Utilities |
Random |
| java.io |
Input and output |
PrintStream |
| java.awt |
Abstract Windowing Toolkit |
Color |
| java.applet |
Applets |
Applet |
| java.net |
Networking |
Socket |
| java.sql |
Database Access |
ResultSet |
| javax.swing |
Swing user interface |
JButton |
| omg.w3c.dom |
Document Object Model for XML documents |
Document |
Organizing Related Classes into Packages

In Java, related classes
are grouped into packages.
Organizing Related Classes into Packages
Package Names
-
Use packages to avoid name clashes
java.util.Timer
vs.
javax.swing.Timer
-
Package names should be unique
-
To get a package name: turn the domain name around:
com.horstmann.bigjava
- Or write your email address backwards
edu.sjsu.cs.walters
Syntax 8.1 Package Specification

Packages and Source Files
- The path of a class
file must match its
package name.
- The parts of the name between periods represent successively nested directories
-
Base directory: holds your program's files
- Place the subdirectory inside the base directory
-
If your homework
assignment is in a directory /home/britney/hw8/problem1
- Place the class
files for the com.horstmann.
bigjava package into the directory:
- /home/britney/hw8/problem1/com/horstmann/bigjava (UNIX)
- Or c:\Users\Britney\
hw8\problem1\com\horstmann\
bigjava (Windows)
- Base Directories and Subdirectories for Packages

Self Check 8.21
Which of the following are packages?
a. java
b. java.lang
c. java.util
d. java.lang.Math
- Answer: (a) No; (b) Yes; (c) Yes; (d) No
Self Check 8.22
Is a Java program without
import
statements limited to using the default and
java.lang packages?
-
Answer: No — you simply use fully qualified names for all
other classes, such as java.util.Random and java.awt.Rectangle.
Self Check 8.23
Suppose your homework assignments are located in the directory
/home/me/cs101
(
c:\Users\me\cs101 on Windows). Your instructor tells you to place your
homework into packages. In which directory do you place the class
hw1.problem1.TicTacToeTester?
- Answer:
/home/me/cs101/hw1/problem1 or, on Windows, c:\Users\me\cs101\hw1\problem1
Unit Test Frameworks
-
Unit test frameworks simplify the task of writing classes that contain many test
cases
-
JUnit: http://junit.org
- Built into some IDEs like BlueJ and Eclipse
-
Philosophy: whenever you implement a class, also make a companion test class.
Run all tests whenever you change your code
Unit Test Frameworks
-
Customary that name of the test class ends in Test:
import org.junit.Test;
import org.junit.Assert;
public class CashRegisterTest
{
@Test public void twoPurchases()
{
CashRegister register = new CashRegister();
register.recordPurchase(0.75);
register.recordPurchase(1.50);
register.enterPayment(2, 0, 5, 0, 0);
double expected = 0.25;
Assert.assertEquals(expected, register.giveChange(), EPSILON);
}
// More test cases
. . .
}
-
If all test cases pass, the JUnit tool shows a green bar:

Self Check 8.24
Provide a JUnit test class with one test case for the
Earthquake class
in Chapter 5.
Self Check 8.25
What is the significance of the
EPSILON parameter in the
assertEquals
method?
- Answer:
It is a tolerance threshold for comparing floating-point numbers. We want the
equality test to pass if there is a small roundoff error.