APCS Class 7 Notes - Classes
1
Learning Goals
▪ To learn how to choose appropriate
classes for a given problem
▪ To understand the concept of cohesion
▪ To minimize dependencies and side
effects
▪ To learn how to find a data
representation for a class
▪ To understand static methods and
variables
▪ To learn about packages
▪ To learn about unit testing frameworks
2
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
3
Discovering Classes
Actors (end in -er, -or) — objects do some kinds of work for
you:
Scanner
Random // Better name: RandomNumberGenerator
Utility classes — no objects, only static methods and
constants:
Math
Program starters: a class with only a main method
The class name should indicate what objects of the class will
do: Paycheck is a better name than PaycheckProgram.
Don't turn a single operation action into a class: Paycheck is
a better name than ComputePaycheck.
4
Self Check 1
What is the rule of thumb for finding classes?
Answer: Look for nouns in the problem description.
5
Self Check 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).
6
Design in g 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.
7
Design in g 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.
8
Design in g 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 * [Link]();
}
. . .
}
Now CashRegister class can handle any type of coin.
9
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
Figure 1 UML class diagram showing dependency
relationship between the CashRegister and Coin
Classes.
The Coin class does not depend on the CashRegister
class.
10
Minimizing Dependencies
Example: printing BankAccount balance
Recommended
[Link]("The balance is now $" + [Link]());
Don't add a printBalance method to BankAccount
public void printBalance() // Not recommended
{
[Link]("The balance is now $" + balance);
}
The method depends on [Link]
Not every computing environment has [Link]
Violates the rule of minimizing dependencies
Best to decouple input/output from the work of your classes
Place the code for producing output or consuming input in a separate
class.
11
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.
12
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.
13
Minimizing Side Effects
A side effect of a method is any externally observable data
modification.
Mutator methods have a side effect, namely the modification of
the implicit parameter.
In general, a method should not modify its parameter
variables.
/**
Computes the total balance of the given accounts.
@param accounts a list of bank accounts
*/
public double getTotalBalance(ArrayList<String> accounts)
{
double sum = 0;
while ([Link]() > 0)
{
BankAccount account = [Link](0); // Not recommended
sum = sum + [Link]();
}
return sum;
}
}
Such a side effect would not be what most programmers
expect.
14
Minimizing Side Effects
The following method mutates the [Link] object, which
is not a part of the BankAccount object.
public void printBalance() // Not recommended
{
[Link]("The balance is now $" + balance);
}
That is a side effect.
Keep most of your classes free from input and output
operations.
This taxi has an undesirable side effect, spraying bystanders
with muddy water.
When designing methods, minimize side effects.
15
Self Check 4
Why does the Coin class not depend on the CashRegister class?
Answer: None of the coin operations require the
CashRegister class.
16
Self Check 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.
17
Self Check 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.
18
Self Check 7
Is the Rectangle class immutable?
Answer: No – translate is a mutator.
19
Self Check 8
If a refers to a bank account, then the call [Link](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.
20
Self Check 8.9
Consider the Student class of Chapter 7. Suppose we add a method
void read(Scanner in)
{
while ([Link]())
addScore([Link]());
}
Does this method have a side effect other than mutating the data set?
Answer: Yes – the method affects the state of the Scanner
argument.
21
C ons is tency
Use a consistent scheme for method names and parameter
variables.
While it is possible to eat with mismatched silverware,
consistency is more pleasant.
22
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;
}
23
Problem Solving: Patterns for Object
Data - Counting Events
A counter that counts events is incremented in methods that correspond to the
events.
Keep a counter:
private int itemCount;
Increment the counter in those methods that correspond to the
events that you want to count:
public void recordPurchase(double amount)
{
purchase = purchase + amount;
itemCount++;
}
Provide a method to clear the counter if necessary:
public void clear()
{
purchase = 0;
itemCount = 0;
}
You may need a method to report the count to the user of the
class.
24
Problem Solving: Patterns for Object
Data - Collecting Values
An object can collect other objects in an array or array list.
A shopping cart object needs to manage a collection of items.
An array list is usually easier to use than an array:
public class Question
{
private ArrayList<String> choices;
. . .
}
25
Problem Solving: Patterns for Object
Data - Collecting Values
Initialize the instance variable to an empty collection:
public Question()
{
choices = new ArrayList<String>();
}
Supply a mechanism for adding values:
public void add(String option)
{
[Link](option);
}
The user of a Question object can call this method multiple times to
add the choices.
26
Problem Solving: Patterns for Object
Data - M a n a g i n g 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 ([Link]() > 0) { name = newName; }
}
Some properties should not change after they have been set
27
Some properties should not change after they have been
set in the constructor
Don’t supply a setter method
public class Student
{
private int id;
. . .
public Student(int anId) { id = anId; }
public String getId() { return id; }
// No setId method
. . .
}
28
Problem Solving: Patterns for Object
Data - Modeling Objects with Distinct
States
Some objects have behavior that varies depending on what
has happened in the past.
If a fish is in a hungry state, its behavior changes.
Supply an instance variable for the current state:
public class Fish
{
private int hungry;
. . .
}
29
Supply constants for the state values:
public static final int NOT_HUNGRY = 0;
public static final int SOMEWHAT_HUNGRY = 1;
public static final int VERY_HUNGRY = 2;
30
Problem Solving: Patterns for Object
Data - Modeling Objects with Distinct
States
Determine which methods change the state:
public void eat()
{
hungry = NOT_HUNGRY;
. . .
}
public void move()
{
. . .
if (hungry < VERY_HUNGRY) { hungry++; }
}
Determine where the state affects behavior:
public void move()
{
if (hungry == VERY_HUNGRY)
{
Look for food.
}
. . .
}
31
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.
32
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.
33
Self Check 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.
34
Self Check 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.
35
Self Check 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.
36
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.
37
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.
38
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.
39
Static Variables and Methods -
Variables
A static variable belongs to the class, not to any object of the
class.
To assign bank account numbers sequentially
Have a single value of lastAssignedNumber that is a property of the
class, not any object of the class.
Declare it using the static reserved word
public class BankAccount
{
private double balance;
private int accountNumber;
private static int lastAssignedNumber = 1000;
public BankAccount()
{
lastAssignedNumber++;
accountNumber = lastAssignedNumber;
}
. . .
}
40
Static Variables and Methods
Every BankAccount object has its own balance and
accountNumber instance variables
All objects share a single copy of the lastAssignedNumber
variable
That variable is stored in a separate location, outside any BankAccount
objects
Static variables should always be declared as private,
This ensures that methods of other classes do not change their values
static constants may be either private or public
public class BankAccount
{
public static final double OVERDRAFT_FEE = 29.95;
. . .
}
Methods from any class can refer to the constant as
BankAccount.OVERDRAFT_FEE.
41
Static Variables and Methods
Figure 5 A Static Variable and Instance Variables
42
Static Variables and Methods -
Methods
Sometimes a class defines methods that are not invoked on an
object
Called a static method
Example: sqrt method of Math class
if x is a number, then the call [Link]() is not legal
Math class provides a static method: invoked as [Link](x)
No object of the Math class is constructed.
The Math qualifier simply tells the compiler where to find the sqrt
method.
43
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 = [Link](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
44
Self Check 8.17
Name two static variables of the System class.
Answer: [Link] and [Link].
45
Self Check 8.18
Name a static constant of the Math class
Answer: [Link]
46
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.
47
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.
48
Problem Solving: Solve a Simpler
Problem First
▪ Simplify the problem
▪ Solve the simpler problem
first
▪ Learn from solving the
simpler problem
▪ Ease the process of solving
the larger problem Arrange
picture
▪ Align along top edge
▪ Separate with small
gaps
▪ When row is full, start
new row
49
Problem Solving: Solve a Simpler
Problem First
Picture class constructor:
public Picture(String filename)
Methods:
public void move(int dx, int dy)
public Rectangle getBounds()
50
Problem Solving: Solve a Simpler
Problem First
Solve series of simpler problems
Draw one picture.
Draw two pictures next to each other.
Draw two pictures with a gap between them.
Draw all pictures in a long row.
Draw a row of pictures until you run out of room, then put one
51
▪ Draw a row of pictures until you run out of room, then put one
more picture in the next row.
National Gallery of Art (see page C-1)
52
Problem Solving: Solve a Simpler
Problem First
Become familiar with Picture class
Pictures in files [Link] ... [Link]
public class Gallery1
{
public static void main(String[] args)
{
Picture pic = new Picture("[Link]");
}
}
National Gallery of Art (see page C-1)
53
Problem Solving: Solve a Simpler
Problem First
Next picture - move to right-most x-coordinate of preceeding
picture:
Picture pic = new Picture("[Link]");
Picture pic2 = new Picture("[Link]");
[Link]([Link]().getMaxX(), 0);
Separate the two pictures by a small gap:
National Gallery of Art (see page C-1)
54
final int GAP = 10;
Picture pic = new Picture("[Link]");
Picture pic2 = new Picture("[Link]");
double x = [Link]().getMaxX() + GAP;
[Link](x, 0);
55
Problem Solving: Solve a Simpler
Problem First
Read the pictures in a loop
National Gallery of Art (see page C-1)
final int GAP = 10;
final int PICTURES = 20;
Picture pic = new Picture("[Link]");
for (int i = 2; i <= PICTURES; i++)
{
Picture previous = pic;
pic = new Picture("picture" + i + ".jpg");
double x = [Link]().getMaxX() + GAP;
[Link](x, 0);
}
56
Problem Solving: Solve a Simpler
Problem First
Start a new row when pictures extend past right margin:
National Gallery of Art (see page C-1)
double x = [Link]().getMaxX() + GAP;
if (x + [Link]().getWidth() < MAX_WIDTH)
{
Place pic on current row.
}
else
{
Place pic on next row.
}
When adding a picture to the current row, update maximum y-
57
▪ When adding a picture to the current row, update maximum y-
coordinate:
maxY = [Link](maxY, [Link]().getMaxY());
To place a picture on the next row, use the remembered
maximum y-coordinate:
[Link](0, maxY + GAP);
58
s ection_5/ [Link]
1 public class Gallery6
2 {
3 public static void main(String[] args)
4 {
5 final int MAX_WIDTH = 720;
6 final int GAP = 10;
7 final int PICTURES = 20;
8
9 Picture pic = new Picture("[Link]");
10 double maxY = 0;
11
12 for (int i = 2; i < 20; i++)
13 {
14 maxY = [Link](maxY, [Link]().getMaxY());
15 Picture previous = pic;
16 pic = new Picture("picture" + i + ".jpg");
17 double x = [Link]().getMaxX() + GAP;
18 if (x + [Link]().getWidth() < MAX_WIDTH)
19 {
20 [Link](x, [Link]().getY());
21 }
22 else
23 {
24 [Link](0, maxY + GAP);
25 }
26 }
27 }
28 }
59
Self Check 8.21
Suppose you are asked to find all words in which no letter is repeated from a list of
words. What simpler problem could you try first?
Answer: Of course, there is more than one way to simplify the
problem. One way is to print the words in which the first letter
is not repeated.
60
Self Check 8.22
You need to write a program for DNA analysis that checks whether a substring of
one string is contained in another string. What simpler problem can you solve first?
Answer: You could first write a program that prints all
substrings of a given string.
61
Self Check 8.23
You want to remove “red eyes” from images and are looking for red circles. What
simpler problem can you start with?
Answer: You can look for a single red pixel, or a block of nine
neighboring red pixels.
62
Self Check 8.24
Consider the task of finding numbers in a string. For example, the string “In 1987, a
typical personal computer cost $3,000 and had 512 kilobytes of RAM.” has three
numbers. Break this task down into a sequence of simpler tasks.
Answer: Here is one plan:
[Link] the position of the first digit in a string.
[Link] the position of the first non-digit after a given position in
a string.
[Link] the first integer from a string (using the preceding
two steps).
[Link] all integers from a string. (Use the first three steps,
then repeat with the substring that starts after the extracted
integer.)
63
Packages
Package: Set of related classes
Important packages in the Java library:
Package Purpose Sample Class
[Link] Language support Math
[Link] Utilities Random
[Link] Input and output PrintStream
Abstract Windowing
[Link] Color
Toolkit
[Link] Applets Applet
[Link] Networking Socket
[Link] Database Access ResultSet
[Link] Swing user interface JButton
Document Object
[Link] Model for XML Document
documents
64
Organizing Related Classes into
Packages
In Java, related
classes are grouped
into packages.
65
Organizing Related Classes into
Packages
To put classes in a package, you must place a line
package packageName;
as the first instruction in the source file containing the classes.
Package name consists of one or more identifiers separated by periods.
To put the Financial class into a package named
[Link], the [Link] file must start as
follows:
package [Link]; public
class Financial
{
. . .
}
A special package: default package
Has no name
No package statement
If you did not include any package statement at the top of your source
file
its classes are placed in the default package.
66
Importing Packages
Can use a class without importing: refer to it by its full name
(package name plus class name):
[Link] in = new [Link]([Link]);
Inconvenient
import directive lets you refer to a class of a package by its
class name, without the package prefix:
import [Link];
Now you can refer to the class as Scanner without the
package prefix.
Can import all classes in a package:
import [Link].*;
Never need to import [Link].
You don't need to import other classes in the same package.
67
Package N ames
Use packages to avoid name clashes:
[Link]
vs.
[Link]
Package names should be unique.
To get a package name: turn the domain name around:
[Link]
Or write your email address backwards:
[Link]
68
Syntax 8.1 Package Specification
69
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 [Link]. bigjava package into
the directory:
/home/britney/hw8/problem1/com/horstmann/bigjava (UNIX)
Or c:\Users\Britney\ hw8\problem1\com\horstmann\ bigjava
(Windows)
70
Figure 6 Base Directories and Subdirectories for
Packages
71
Self Check 8.25
Which of the following are packages?
[Link]
[Link]
[Link]
[Link]
Answer: (a) No; (b) Yes; (c) Yes; (d) No
72
Self Check 8.26
Is a Java program without import statements limited to using the default and
[Link] packages?
Answer: No — you simply use fully qualified names for all
other classes, such as [Link] and
[Link].
73
Self Check 8.27
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
[Link]?
Answer: /home/me/cs101/hw1/problem1 or, on
Windows, c:\Users\me\cs101\hw1\problem1
74
Unit Test Frameworks
Unit test frameworks simplify the task of writing classes that
contain many test cases.
JUnit: [Link]
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.
75
Unit Test Frameworks
Customary that name of the test class ends in Test:
import [Link];
import [Link];
public class CashRegisterTest
{
@Test public void twoPurchases()
{
CashRegister register = new CashRegister();
[Link](0.75);
[Link](1.50);
[Link](2, 0, 5, 0, 0);
double expected = 0.25;
[Link](expected, [Link](), EPSILON);
}
// More test cases
. . .
}
If all test cases pass, the JUnit tool shows a green bar:
Figure 7 Unit Testing with JUnit
76
Self Check 8.28
Provide a JUnit test class with one test case for the Earthquake class in Chapter
5.
Answer: Here is one possible answer.
public class EarthquakeTest
{
@Test public void testLevel4()
{
Earthquake quake = new Earthquake(4);
[Link]("Felt by many people, no destruction",
[Link]());
}
}
77
Self Check 8.29
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.
78