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.