CS
99
Summer
2001 7.18
Lecture Notes 6
Reading
4.1 Savitch
Objects, Classes & Methods
·
Up
until now, we have largely avoided the object-oriented nature of Java.
·
All
the programs we've written have been centered around a single main method,
where all the action has gone in inside method main:
class MyProgram {
public static void
main( String[] args ) {
<ALL
THE ACTION>
}
}
·
And
for the simple programs we've done so far, that's been sufficient. Indeed, the programming assignments have
been intentionally that simple because the goal was to get you to understand
how to use the basic programming constructs like direct sequencing, conditional
branching, and conditional looping.
·
But
now it's time to get more complex.
·
When
you want to write more involved programs, you have to move beyond mere
statements residing in a single method main.
A Baseball Game
·
Imagine
yourself trying to write a program (in Java) that simulates a Baseball game
(think about your favorite Nintendo baseball game for example). How would you go about doing that with the
knowledge you know now?
·
It
would be hard if not downright
impossible. Think of the millions of
statements you'd have to have in method main, and all the thousands of
variables you would have to keep track of!
It would take months or years to finish; I myself wouldn't know where to
begin. Worse still, your program
wouldn't even be that interesting because it would have to be entirely
text-based with your present background.
·
So
how would a more experienced Java programmer go about doing it?
·
Such
a programmer would start by thinking in terms of the objects and classes he
would need. This is where the power of
object-oriented programming (OOP) scintillates.
·
In
OOP, everything is centered round the data.
You think about the objects--the things--that
comprise the problem you're trying to solve, and then think about the various
properties of those objects. These
objects and their properties will become your class definitions.
So
what do we mean exactly by objects and classes?
Objects
·
Think
about objects in the world around you.
How would you describe them?
·
For
instance, let's think about a bicycle.
A bicycle has particular characteristics: it has two wheels, front and
back brakes, a certain number of gears, a color, and a style (mountain or BMX
or otherwise). Formally, we say these
characteristics comprise the bicycle's state.
·
We
can also describe a bicycle by what it does, such as the fact that it can move,
it can turn, it can brake, it can shift gears.
These activities define the bicycle's behavior.
·
In
Java, all software objects (defined by class definitions), have a state and a
set of behaviors.
·
Objects
contain variables and methods; the values of the variables describe the
object's state, and the methods define the object's behaviors.
·
But
unlike real world objects, software objects don't have to represent tangible
items. An error message can be an
object, for instance. The possibilities
are limitless!
Classes
·
Objects
are defined by classes. A class is the model, or pattern, from
which an object is created. Consider
the following analogy:
·
An
architect when designing a house starts with a blueprint. The blueprint defines the important
characteristics of the house: walls, windows, doors, electrical outlets, and so
on. Once the blueprint is created,
several houses can be built from it.
·
In
one sense, the houses built from the blueprint are different. They are physically in different places,
with different addresses, different furniture, and different people live in
them. Yet in many ways they are the
"same" house. The layout of
the rooms and other crucial characteristics (defined by the blueprint) are the same
in each. To create a completely
different house, with a different layout and different walls, and different
window placements and door placements, and electrical outlet placements, we
need a brand new blueprint.
·
Well,
a class is a blueprint of an object. It
defines the types of data that will be held in an object, and defines the code
for the methods. But a class is not an
object anymore than a blueprint is a house.
After we have the class defined, we can create an object from it. The process of creating an object is called
instantiation. Every object is an
instance of a particular class. And
just as we can create several houses from the same blueprint, we can
instantiate several objects from the same class. They are the same type of object, with the same methods, but each
object is unique because each has its own data space with possibly different
values.
Instantiation
·
In
many ways an object can be thought of as a new type of variable. The class defines its type. In fact, you've already used one kind of
object and class definition already: TokenReader!
·
Consider
the following two declarations and assignments:
int x = 25;
TokenReader in = new TokenReader( System.in );
·
Don't
the two lines look very similar? The first line declares a variable called x of
type int and assigns it a value of 25.
The second line declares a variable called in of type TokenReader and
assigns it to a new TokenReader object that's prepared to read from the
keyboard ( that's what System.in means.
Incidentally, System.in is itself an object! )
·
Notice
the word new between the equals sign
and TokenReader( System.in )? That's
how you tell Java to instantiate a new object.
The primitive variable types like int, double, char, boolean, etc.,
don't need any new's in their
assignment statements: that's why we call them primitive.
Back to the Baseball Game
·
Let's
think about the baseball game again. If I was going to write a program to do
it, I would start by asking myself what kinds of things are in a baseball game.
Here are some of the suggestions you guys came up with: Players, Teams, Umpires, Stadiums, Innings,
Baseball Physics, Balls, Bats, Gloves, Grass, etc. etc.
·
Consider
the Player object.
·
What
kinds of properties does a player have?
A batting average (BA), a name, a number, a team, a phenotype (body
type), a position, a fatigue factor, and so on.
·
What
kinds of behavior does a player exhibit?
A player can run, score, throw, catch, swing a bat, etc.
·
If
you think about it a bit more, you can come up with other properties for the
player that don't really have to do with a real player perhaps but have more to
do with what you might want a player in your application to do, such as be able
to draw himself, is he tired?, output his information, etc.
·
With
all this behind us, we can now start to write our Player class:
class Player {
double
battingAverage;
String name;
int number;
String team;
String phenotype,
String position,
double fatigue;
public boolean
throw( Ball b ) {
/* code for
throwing */
}
public boolean
catch( Ball b ) {
/* code for
catching */
}
public boolean
isTired() {
return
fatigue > 0.6;
}
public void draw()
{
/* code for
drawing */
}
/* etc., etc. */
}
·
These
properties are only tentative! Maybe
later, we won't want to use a String to describe the team or to describe the
phenotype (we might introduce a Phenotype class). That's how real world programming works: we start out with things
that we think we need in the beginning, but later as things develop, we change
things … but at least it's a start.
·
Next
we go on to define the properties of the other objects in the game. One class we haven't mentioned is the
Application class. That's the one that
will have the main method, it is the one that's responsible for coordinating
the activities of the video game itself; it's the engine that makes everything
run.
·
We
still have an enormous amount of planning and programming ahead of us, but at
least the outlines of what needs to be done are taking shape in an organized
way. This is much, much better than how
it would have been had we tried to keep everything in one single main method in
one class.
A problem with triangles
·
Let's
leave the baseball game for now and try to do something much simpler.
·
Imagine
you wanted to write a program that allows the user to enter in data for various
triangles and examines their properties.
·
Think
for a moment how you would go about doing this using only the primitive
variables that we have in Java and just your main method. If the user was going to be playing around
with 5 triangles say, you'd have to have at least 15 variables for each of the
sides of the triangle. Then you'd have to design your program in such a way
that it manipulated all those 15 variables in an organized fashion. When the user wanted to find out if the
first triangle was equilateral or what it's area was, how would you write the
code to do that? What if the user
wanted to do that for the fifth triangle?
Where would you put the code to do that? Sounds complicated, and it would be!
·
Wouldn't
it be nice if, instead of just manipulating primitive variables, we could actually
have entire Triangles as data variables? Instead of 15 variables, we could have
just 5. Wouldn't it be nice too if the
way we asked Triangle 1 if it was equilateral was the same way we could asked
Triangle 5 if it was equilateral?
·
Fortunately
there's a way to do just that. Let's
define a brand new kind of object called Triangle.
Properties of the Triangle
class
·
So
… what kinds of properties does a Triangle have? A Triangle has three sides.
Do we need any more information than that? Not really, since if we the three sides we can figure out
anything else we want to know about the Triangle itself ( think back to high
school and how SSS is complete information ).
With the 3 sides, we can figure out the angles, the area, the perimeter,
whether it's equilateral, right or scalene or anything else we'd want to know.
·
Caveat:
it's not entirely true that the 3 sides are always going to be all that we
need. It depends on the context. If we're actually going to draw the triangles, then we might need
other data: such as what is the triangle's color, what is its position on the
screen, what is its orientation, etc.
·
But
for now the three sides are sufficient.
These will the variables of
class Triangle.
·
What
kinds of questions can we ask a triangle?
We could ask it what it's area is, what it's perimeter is, whether its a
right triangle, whether its an equilateral triangle, and so forth. These will be the methods of class Triangle.
·
Let's
write a preliminary specification for the class then:
class Triangle {
int a, b, c; // the sides of the triangle
/* Constructor */
Triangle( int s1,
int s2, int s3 ) {
a = s1; b =
s2; c = s3;
}
/* Returns the
perimeter of the triangle */
public double
perimeter() {
return a + b
+ c;
}
/* Returns the
area of the triangle */
public double
area() {
/* use
Heron's formula */
}
/* Returns true if
the triangle is equilateral */
public boolean
isEquilateral() {
return (a ==
b) && (b == c);
}
/* other methods
go here */
}
·
We
can add this class to our project and call it Triangle.java (just the way we've
been adding TokenReader.java to our projects).
·
Having
done so, we can now create Triangle objects!
·
For
instance, the following bit of code, assuming the methods actually worked would
be legal:
Triangle myTri = new Triangle( 3, 4, 5 );
if ( myTri.area() > 10 )
System.out.println("The
area of your triangle is greater than 10");
if ( myTri.isEquilateral() )
System.out.println("Your
triangle is equilateral.");
·
Notice
the "." notation. That's how
we access an object's properties. We'll
talk more about constructors and methods in Monday's lecture. Please do the reading 4.1 in Savitch.