CS 101
Computer Science 1 in Java
Prof. Alvarez
Object-Oriented Modeling using Instantiable Classes
The Java language follows an objected-oriented approach.
This means that it uses objects to model data items.
Objects are grouped into classes. The objects of a class
share similar properties and behaviors.
Example of Object-Oriented Modeling: the Dice Table
Consider a game involving rolling standard six-sided dice on a table
as shown below.
The table can accomodate zero, one, or more dice.
There are three basic operations that can be carried out with a die:
creation, rolling, and deletion.
Dice must first be placed on the table ("created").
Any die that is on the table may be rolled.
The newest die on the table may be taken off the table ("deleted").
The images below show the result of rolling die number 5,
which is located in the lower left corner of the table.
Creating a die
Initial table configuration
Initially, the dice table is empty.
Dice can be created (and brought onto the table)
by pressing the "Create Die" button.
After pressing the "Create Die" button
Additional dice may be brought onto the table by repeatedly pressing
"Create Die". One may also delete the last die by pressing the
corresponding button.
Rolling a die
Since there may be multiple dice on the table, rolling a die
requires that the number of the die be specified. This is done
by writing the number in the text field located in the top right
corner of the table. The "Roll Die" button should then be pressed.
Before rolling
After rolling
Rolling a die results in a random face number between 1 and 6
being assigned to the chosen die.
Objects and classes in the DiceTable program
The RollingDie class
Notice that all dice are created equal in the sense that they
share a common set of behaviors. Namely, they all have 6 sides
and exist solely for the purpose of being rolled. Because of
this, we define a class named RollingDie. Each instance of the
RollingDie class represents a single die. The RollingDie class
represents the abstract concept of a die that can be rolled.
To create an instance of the RollingDie class, the constructor
method of the class is invoked, using the keyword new
followed by the class name RollingDie() (note the parentheses).
Once created, each individual instance of the RollingDie class
"understands" a method (message) named roll() that causes a die
to randomly select a face between 1 and 6 when it receives the
roll() message.
The Javadoc documentation for
the RollingDie class describes additional details.
The DiceTable class
The playing table shown above contains several individual dice.
Each of these dice is represented by an instance of the
RollingDie class. The table itself is in turn an instance
of a separate class, DiceTable. The DiceTable class is a
"client" of the RollingDie class, in the sense that RollingDie
instances are used within the DiceTable class.
As with RollingDie, it is also possible to create instances
of the DiceTable class.
A DiceTable instance represents a playing table with zero,
one, or more dice on it. It allows the human player to place
new dice on the table, roll an existing die, or delete the most
recently created die. When a human player interacts with the
table program, he/she is really using an instance of the DiceTable class.
Sample client code of the RollingDie class
Before taking a look at how the RollingDie class can be implemented
(written), consider how to use the class within a client program.
Basically, a client program such as DiceTable will create one or
more instances of the RollingDie class and send them messages
in order to achieve a desired effect. Here's an example involving
repeatedly rolling two dice until a sum of 12 is obtained:
RollingDie lucky = new RollingDie();
RollingDie trusty = new RollingDie();
int rollCount = 0;
while (lucky.getFace() + trusty.getFace() != 12) {
lucky.roll();
trusty.roll();
rollCount++;
}
System.out.println("You rolled a 12 in only " + rollCount + " tries");
Notice that the precise way in which RollingDie is written should
not concern the writer of the client program, as long as he or she
trusts that the behaviors described in the specification of the
RollingDie class will be provided as promised.
Inside the RollingDie class
Now consider how to implement (write) the RollingDie class so
that it provides the behaviors that client programs will be
relying on.
A simple implementation of the RollingDie class is shown below.
This implementation provides the behaviors that are exhibited by
individual dice in the DiceTable program. A discussion follows.
public class RollingDie {
// private instance variables; each RollingDie instance
// has its own copy of each of these instance variables
private int numberOfSides, face;
// constructor method; creates a six-sided RollingDie instance
public RollingDie() {
numberOfSides = 6;
roll();
}
// getFace() returns the face that is currently showing on the recipient
// the recipient instance is not modified by getFace()
public int getFace() {
return face;
}
// getIcon() returns a graphical representation of the current face
public ImageIcon getIcon() {
if (face==1)
return new ImageIcon("one.jpg");
else if (face==2)
return new ImageIcon("two.jpg");
else if (face==3)
return new ImageIcon("three.jpg");
else if (face==4)
return new ImageIcon("four.jpg");
else if (face==5)
return new ImageIcon("five.jpg");
else if (face==6)
return new ImageIcon("six.jpg");
else
return new ImageIcon();
}
// roll() randomly assigns a face value to the recipient instance
// the recipient instance is potentially modified by roll()
public int roll() {
face = (int) (numberOfSides*Math.random() + 1);
return getFace();
}
}
Instance variables
Every instance of an instantiable class like RollingDie has internal
variables that store state information for that instance. These internal
variables are called instance variables.
Syntactically,
there are two determining factors in making a variable an instance variable:
- the variable should be declared inside the class body but outside
the bodies of all of the methods of the class
- the variable's declaration should not include the keyword
static.
Instance variables are declared once, within the class definition,
in accordance with the above.
However, every instance of the class will have its own copy of
each instance variable. Information can be read from and written
into an object's instance variables by sending the object messages
embodied as invocations of the instance methods of the class.
Methods
An instantiable class like RollingDie has three basic kinds of
instance-related methods:
constructors, selectors (accessors), and modifiers (mutators).
All of these methods must be declared without using static
in the header.
- Constructors allow new instances of the class to be created.
The name of a constructor must match the name of the class exactly,
and no return type should be provided in the constructor header:
// constructor method; creates a six-sided RollingDie instance
public RollingDie() {
numberOfSides = 6;
roll();
}
- Selectors provide read-only access to the information in the
recipient instance's instance variables:
// getFace() returns the face that is currently showing on the recipient
// the recipient instance is not modified by getFace()
public int getFace() {
return face;
}
- Modifiers provide read-write access to the information in the
recipient instance's instance variables:
// roll() randomly assigns a face value to the recipient instance
// the recipient instance is potentially modified by roll()
public int roll() {
face = (int) (numberOfSides*Math.random() + 1);
return getFace();
}