Introduction to Computer Science Classes and Methods I »Objects »Instance Methods »Formal...

218
Introduction to Computer Science Classes and Methods I » Objects » Instance Methods » Formal Parameters, the Stack, Call-by- Value, Scope of Variables, Mutable vs. Immutable Classes » Object Variables as References (i.e., addresses) » Example: Encapsulation Tic-tac-toe board Unit 7
  • date post

    19-Dec-2015
  • Category

    Documents

  • view

    224
  • download

    2

Transcript of Introduction to Computer Science Classes and Methods I »Objects »Instance Methods »Formal...

Introduction to Computer Science

• Classes and Methods I» Objects» Instance Methods» Formal Parameters, the Stack, Call-by-Value,

Scope of Variables, Mutable vs. Immutable Classes

» Object Variables as References (i.e., addresses)» Example: Encapsulation

Tic-tac-toe board

Unit 7Unit 7

7- 2

Once Again, With Feeling

• We have already seen some examples of objects, instance variables, and instance methods

• The purpose of this section is to go over the concepts in much more detail, to learn new things about objects and their use, and to see examples of their use

7- 3

An Object is a Collection of Attributes and Operations

• An object encapsulates data values within a single entity, along with operations to be performed on those data values

• An object’s behavior is often general enough to be reused in multiple situations

• Classes, the basis of objects, provide the basis for deriving other classes through inheritance

7- 4

The Structure of Classes

class name {

declarations

constructor definitions

method definitions

}

instance variablesand symbolic constants

how to create and initialize objects

how to manipulate those objectsThese parts of a class can actually be in any order

7- 5

Methods First

• Two kinds of methods: Class methods and Instance methods

• Math.sqrt is an example of a Class method; “Math” is the name of a class, and we invoke the sqrt method in that class

• main is also a Class method

• I’m still not going to talk more about Class methods now; only Instance methods in this lecture

7- 6

Methods Calling Methods

• Each method contains a sequence of statements to be executed

• When a method f( ) calls a method g( ), Java begins executing the statements of g( ) but remembers that it was in the middle of f( )

• When g( ) is done, Java returns to the executing f( ), continuing where it left off

7- 7

Methods Calling Methods:Execution is Nested

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void g ( ) { System.out.println(“A!”); System.out.println(“B!”); System.out.println(“C!”); System.out.println(“D!”);}

7- 8

Of Course, Nesting can be to Multiple Levels

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void g ( ) { System.out.println(“A!”); System.out.println(“B!”); System.out.println(“C!”); System.out.println(“D!”);}

void e ( ) {......obj.f( );...}

1 324

5

68 7

9

A key point is that Java remembers where it was, and resumes execution there when returning from a method call

7- 9

Methods Returning Values

• Some methods return a value (int, double, boolean, etc.)

• A method that returns a value can be used wherever Java wants a value of that type (e.g., in an expression)

wage = sinp.readInt( );• Use the statement

return value;to return a value from a method, where the value is of the appropriate type

7- 10

Method Not Returning a Value

• Other methods do not return a value, i.e., they return type void

• A call to a method that returns no value constitutes a complete Java statement

bill.printTime( );• Use the statement

return;to return from a void method, or you can just let the method execute until the end, and it will automatically return

7- 11

Formal Parameters

• The heading of a method specifies the return type, and the identifier and type of each parameter to the method

• These identifiers are called the formal parameters of the method

• When the method is called, the call supplies the actual parameters (or arguments) of the call

7- 12

Formal Parameters of a Method

boolean checkValue (int col, int row, int limit)

returned typeof method

nameof method

three formal parametersof method, each of type int

Call to checkValue( ) (as an expression):bill.checkValue(3, 7, 9)

assigns 3, 7, and 9 to the formal parameters col, row, and limit, respectively; then executes the method

7- 13

Matching Arguments andFormal Parameters

bill.checkValue(3, 7, 9)

boolean checkValue (int col, int row, int limit) {

if (row > limit)...

else...

}There must be an (exact) match between the number, order, and type of the actual parameters and the formal parameters (except for things like an int value being automatically converted to a double).

7- 14

Legal?

double findValue (int start,double end, int

limit)

• bill.findValue(3, 5.0, 9)• bill.findValue(5.0, 3, 9)• bill.findValue(5, 3, 9)• bill.findValue(5, 3)• bill.findValue(5, 3, 9, 4)• bill.findValue(x, y, z)

7- 15

Local Variables

• Instance methods can also have local variables, defined within the method (in addition to the class attributes)

• These variables store values during the method’s executionboolean checkValue (int col, int row, int limit) {

double d;if (row > limit)

...}

7- 16

Class Abstraction

• The most important stage in writing a class is to get an abstraction of the class done first.–What does an object of this type represent?–What is its interface?–What is its internal state?

• This means you have to know what should be the internal state (variables) and also the behavior/interface (methods) of the class before you start to write your class code.

7- 17

Objects and Classes

• The relationship between Classes and Objects can be seen as the relationship between a blueprint/model and the actual object built from it.

– Example: Blueprint of a house (class) and the house (object)

• The class defines:– The type of data that will be held in an object

– The code for the methods of the object

• In order to use a class you must instantiate an object from it.

– This corresponds to building the house from the blueprint

– There may be many objects from a single class

7- 18

An Example Class

• The Time class will be used to create objects the represent a time (hour and minute) within a day

• It comes with methods for creating and manipulating hours and minutes

• It has two internal integers, _hour (between 0 and 23), and _minute (between 0 and 59)

_hour_minute

Time addMinutes( int m )void printTime( )

Time

7- 19

Class Abstraction!

• The Time class will be used to create objects the represent a time (hour and minute) within a day

–What does an object of this type represent?

• It comes with methods for creating and manipulating hours and minutes

–What is its interface?

• It has two internal integers, _hour (between 0 and 23), and _minute (between 0 and 59)

–What is its internal state?

7- 20

Conventions…

• We will use an underscore before the name of a variable that belongs to the class (as opposed to a local variable that belongs to a method):

_hour

_minute

• This is “just” a Java convention, but stick to it, for everyone’s sake…

7- 21

The Time objects

• The objects themselves, created from the Time class, can hold values for _hour and _minute

_hour_minute

Time addMinutes( int m )void printTime( )

TimebillAttributes: _hour = 7 _minute = 18Methods: Time addMinutes(int m) void printTime ( )

scottAttributes: _hour = 14 _minute = 41Methods: Time addMinutes(int m) void printTime ( )

7- 22

The Time Class’s Interface

• A method that adds m minutes to an existing Time object’s time, returning a new Time object with the new time

Time addMinutes(int m)

• A method that prints the value of a Time object

void printTime( )

• A constructor, for creating and initializing a Time object

Time (int h, int m)

7- 23

Encapsulation

• The internal state of an object is not directly accessible to other parts of theprogram

• Other parts of the programcan only access the objectusing its interface

• We say that the state isencapsulated or hidden

• This gives modularityto the program

addMinutes(int m)

printTime()

.

.

.

.

.

.

•_hour

•_minute

7- 24

Encapsulation

• Hiding what’s inside the object is a big part of Object Oriented Programming

• Programming projects get complicated

• You can only hold (7 plus or minus 2) facts at a time in your brain

• Break the big problem into individual objects that each works as a “black box”

7- 25

Not Just a Pretty Interface

• You are told to implement the Time class

• Your boss tells you what the class’s interface is; there’s another group (in San Jose) that’s building the rest of the program, and they will use the Time class that you build

• The details of what goes on inside the class are hidden

• The important thing is: the San Jose group doesn’t need to know about the implementation of Time, only its interface!

7- 26

Clients and Classes

• Methods that use the Time class are called clients of the class

• To keep roles clear, both clients and classes have certain rights

• This is a “division of labor”

7- 27

Rights of a Class

• Define the public interface of the class

• Hide any and all private details of implementation

• Protect internal, private data from access by a client

• To change the implementation details at any time, provided the public interface stays the same

7- 28

You Get to “Fine-Tune” the Encapsulation

• The private modifier specifies an identifier that is only visible within the class. Usually used for fields (instance variables) of the class.

• The public modifier specifies an identifier that is accessible to all other classes. Usually used for methods.

7- 29

Rights of a Client

• To declare variables of the class type

• To create instances (objects) of the class, using the class constructors

• To send messages to instances of the class by invoking the instance methods defined by the class

• To know the public interface of the class

• To know which instance methods alter the instance

7- 30

The Structure of theTime Class Definition

class Time {

declarations

public Time (int h, int m) {...}

public Time addMinutes (int m) {...}

public void printTime ( ) {...}

}

constructor definition

method definition

method definition

7- 31

API Documentation

• Your classes are often intended to be used by other programmers

• Programmers that use your class are not interested in the way it is implemented. They want to use it as a whole and are only interested in what it does and how to use it.

• API (Application Programmer Interface) documentation is a description of the interface of the class intended for the application programmer who wants to use it.

• To use the class, we need not (and should not) look at the code. All that is needed is the class API.

7- 32

API Documentation

• The JDK contains a special tool for the generation of API documentation for your classes, called javadoc.

• Any documentation which is part of the interface begins with /** (double asterisk) and ends with */

• javadoc takes as input Java programs and automatically generates documentation using:

– the public/protected method signatures

– the documentation comments (enclosed by /** … */).

• The output is an HTML file which can be viewed by an internet browser.

7- 33

class Clock API Documentation

/** * A clock represents a point of time in a 12 * hour period within a precision of seconds. * Its range: 1:00:00 -- 12:59:59. */public class Clock { private int _hours; private int _minutes; private int _seconds; /** * Constructs a Clock: Sets the clock to the * specified time. */ public Clock(int hours, int minutes, int seconds){ //… }

7- 34

Clock API Documentation – continued

/** * Constructs a Clock: Sets the clock to 12:00:00 */ public Clock(){ this(12,0,0); }

/** * Advances this clock by 1 second. */ public void secondElapsed() { //… }

//…

7- 35

Javadoc Process

.java file .html filejavadoc

View using a browser

7- 36

Clock javadoc – page 1

7- 37

Clock javadoc – page 2

7- 38

What should you comment?

• You should put a documentation comment for the class itself and for any member of the class which is part of its interface

• All public constructors and methods should have documentation comments

• Private methods are not part of the interface of the class, thus javadoc skips them. (But you should still comment them for internal purposes.)

• In the rare cases that there are public fields, they should have documentation comments

7- 39

API Documentation

• Remember that documentation comments are written for programmers who use your class as a whole. They should describe only – What the class does;

– How to use it. • Documentation comments should not describe how a

class is implemented.• Documentation comments should be

– Short and descriptive;– Written in a simple language (ENGLISH);– Accurate.

• Assume that the reader doesn’t know anything about your class

7- 40

API Documentation Tags

• Documentation comments can also include tagged paragraphs that give a standard way to document several features of the interface such as method parameters, return values, etc.

• A tagged paragraph begins with the symbol @ followed with a tag keywords. Tags: @see, @author, @version, @param, @return, @exception.

• Documentation comments text can include HTML tags.

7- 41

@param tag

/**

* Changes the current time to hour:minute:second

* @param hours The new hour value.

* @param minutes The new minutes value.

* @param seconds The new seconds value.

*/

public void setTime(int hours,

int minutes,

int seconds) {

this.hours = hours;

this.minutes = minutes;

this.seconds = seconds;

}

7- 42

setTime generated javadoc

7- 43

@return

/**

* Returns the current hour

* @return The current hour (between 1 and 12).

*/

public void getHour() {

return hours;

}

7- 44

getHour javadoc

7- 45

Naming

• The names you use for your class and for its public methods are part of the class API

• Good descriptive naming is crucial for a clear API

• General rules about naming:– Follow the Java conventions

– Use descriptive names

– Do not use abbreviations!

– Make names long enough, but not unnecessarily long

– Consists of words in English with no abbreviations

– Use a dictionary

• Read the style guidelines!

7- 46

The Structure of theTime Class Definition

class Time {

declarations

public Time (int h, int m) {...}

public Time addMinutes (int m) {...}

public void printTime ( ) {...}

}

constructor definition

method definition

method definition

7- 47

Creating a Time Object

As you know:

Time dawn;dawn = new Time(5, 35);

or, all at once,

Time dawn = new Time(5, 35);

declarationcreation and assignment

7- 48

What’s Really Happening?

• When we declare a variable of a simple type, we actually get a location in memory to store the value:

int temperature;

gives us:

temperature

7- 49

scottAttributes: hour = 14 minute = 41Methods: Time addMinutes(int m) void printTime ( )

scottAttributes: hour = 14 minute = 41Methods: Time addMinutes(int m) void printTime ( )

What’s Really Happening?

• When we declare a variable of an object type, we get a reference in memory to an object (the object’s address); the object is stored elsewhere:

Time dawn = new Time(5, 35);

gives us:

dawnthe heap

dawnAttributes: _hour = 5 _minute = 35Methods: Time addMinutes(int m) void printTime ( )

scottAttributes: hour = 14 minute = 41Methods: Time addMinutes(int m) void printTime ( )

7- 50

What’s Happening Behind the Scenes?

• We just talked about object variables and how they “point” to an object in the heap

• Let’s look at what’s going on in the computer’s memory, behind the scenes

• You don’t handle this yourselves, Java does. But it helps (e.g., understanding parameter passing) if you understand what is going on

7- 51

What’s All This I Hear About “Pointers”?

Time lunchtime = new Time(12, 0),dinnertime = new Time(0, 0);

lunchtime

lunchtimeAttributes: _hour = 12 _minute = 0Methods: …

dinnertime

dinnertimeAttributes: _hour = 0 _minute = 0Methods: …

7- 52

Object Variable Contains Object’s Address in the Heap

• An object variable represents the address, in computer memory, of an object.

dinnertime

dinnertimeAttributes: _hour = 0 _minute = 0Methods: …

heap

7- 53

Object Variable Contains Object’s Address in the Heap

dinnertime

dinnertimeAttributes: _hour = 0 _minute = 0Methods: …

32476

32476heap

• An object variable represents the address, in computer memory, of an object.

7- 54

Thanks for the Memory

• When we declare simple variables inside the computer, memory is set aside:

int totalMinutes, days;double temperature;

[1247][1248][1249][1250][1251][1252][1253][1254]

undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefined

totalMinutes temperaturedays

Part of the Computer’s Memory:

7- 55

Thanks for the Memory

• Notice that–Different types of simple variables might take

up different amounts of memory

–Each variable has an “address” in memory

• But Java handles all this automatically

[1247][1248][1249][1250][1251][1252][1253][1254]

undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefined

totalMinutes temperaturedays

7- 56

Thanks for the Memory

• An ordinary variable names its piece of memory; an assignment to the variable changes the value stored there; we make assignments to it:totalMinutes = 43;days = 12;temperature = 98.6;

[1247][1248][1249][1250][1251][1252][1253][1254]

undefinedundefinedundefinedundefined

43 12 98.6

totalMinutes temperaturedays

7- 57

What Happens withObject Variables

• When an object variable is declared:–the computer sets aside a memory

location to hold the (eventual) address of the object

Time lunchtime;

[1247][1248][1249][1250][1251][1252][1253][1254]

undefinedundefinedundefinedundefined

43 12 98.6

totalMinutes temperaturedays

lunchtime

7- 58

What Happens with Pointers

• When an object is created and assigned:–the computer sets aside enough memory in

the heap to hold the appropriate object–the address that marks the object location

in the heap is given to the object variable

lunchtime = new Time(12, 0);

[1247][1248][1249][1250][1251][1252][1253][1254]

undefinedundefinedundefined

43 12 98.6

totalMinutes temperaturedays

lunchtime

27193

7- 59

What Happens with Pointers

[1247][1248][1249][1250][1251][1252][1253][1254]

undefinedundefinedundefined

43 12 98.6

totalMinutes temperaturedays

lunchtime

lunchtimeAttributes: _hour = 12 _minute = 0Methods: …

27193

27193

heap

7- 60

What Happens with Pointers

[1247][1248][1249][1250][1251][1252][1253][1254]

undefinedundefinedundefined

43 12 98.6

totalMinutes temperaturedays

lunchtime

lunchtimeAttributes: _hour = 12 _minute = 0Methods: …

heap

Sometimes I’ll draw it this way

7- 61

scottAttributes: hour = 14 minute = 41Methods: Time addMinutes(int m) void printTime ( )

scottAttributes: hour = 14 minute = 41Methods: Time addMinutes(int m) void printTime ( )

What’s Really Happening (again)?

• When we declare a variable of an object type, we get a reference in memory to an object (the object’s address); the object is stored elsewhere:

Time dawn = new Time(5, 35);

gives us:

dawnthe heap

dawnAttributes: _hour = 5 _minute = 35Methods: Time addMinutes(int m) void printTime ( )

scottAttributes: hour = 14 minute = 41Methods: Time addMinutes(int m) void printTime ( )

7- 62

Using the Object’s Methods

• OK, so now we’ve created dawn• The constructor has initialized the object

with the values _hour=5 and _minute=35

• We have two methods at our disposal:–addMinutes( ), which takes an integer

argument and returns a new Time object

–printTime( ), which takes no arguments and prints the time

7- 63

Object Operations

Time dusk = dawn.addMinutes(60 * 12);dusk.printTime( );

These two simple Java statements actually cause a large number of actions.

•“Time dusk” declares a new Time object

•“dawn.addMinutes(60 * 12)” creates a new reference to a Time object, which is then assigned to “dusk”

•“dusk.printTime( );” sends dusk the message to print its value

7- 64

dawn.addMinutes(60 * 12)

dawn

dawnAttributes: _hour = 5 _minute = 35Methods: Time addMinutes(int m) void printTime ( )

addMinutes(60 * 12)

7- 65

dawn’s addMinutes( ) Method Creates a New Time Object (it must have used a constructor)

dawn

dawnAttributes: _hour = 5 _minute = 35Methods: Time addMinutes(int m) void printTime ( )

Attributes: _hour = 17 _minute = 35Methods: Time addMinutes(int m) void printTime ( )

(it still has no namesince it isn’t assigned to any variable)

7- 66

Then This New Object is Assigned to the Time Variable dusk

Time dusk = dawn.addMinutes(60 * 12);

dawn

dawnAttributes: _hour = 5 _minute = 35Methods: Time addMinutes(int m) void printTime ( )

Attributes: _hour = 17 _minute = 35Methods: Time addMinutes(int m) void printTime ( )dusk

dusk

7- 67

Then dusk is Sent the printTime( ) Message, and Does its Thing

dusk

duskAttributes: _hour = 17 _minute = 35Methods: Time addMinutes(int m) void printTime ( )

printTime( )

dusk.printTime( );

(and it prints“5:35PM”)

7- 68

Let’s Write a Program That’s a Client of the Time Class

• We want the following output:

8:30AM ____________________9:00AM ____________________9:30AM ____________________10:00AM ___________________

class Schedule { public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( ); System.out.println(“ ____________________”); start = start.addMinutes(30); start.printTime( ); System.out.println(“ ____________________”); start = start.addMinutes(30); start.printTime( ); System.out.println(“ ____________________”); start = start.addMinutes(30); start.printTime( ); System.out.println(“ ____________________”); }}

7- 70

One Class Making Use of an Outside Class

• The class Schedule must be in a file called Schedule.java

• The class Time must be in a file called Time.java

• Both must be compiled (although the Java compiler will handle the second compilation automatically)

7- 71

Assignments

• The only new part of the program is the assignment, to the object variable start, the result of the addMinutes(30) message:

start = start.addMinutes(30);

Let’s look at what’s going on.

7- 72

Creation of Time Object start

Time start = new Time(8, 30);

start

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

7- 73

start.addMinutes(30)

start

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

addMinutes(30)

7- 74

start’s addMinutes( ) Method Creates a New Time Object (it must have used a constructor)

start

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

Attributes: _hour = 9 _minute = 0Methods: Time addMinutes(int m) void printTime ( )

(it still has no namesince it isn’t assigned to any variable)

7- 75

Then This New Object is Assigned to the Time Variable start

start = start.addMinutes(30);

start

Attributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

Attributes: _hour = 9 _minute = 0Methods: Time addMinutes(int m) void printTime ( )

start

(the old Time object is thrown away, automatically)

7- 76

The Time Class

• Isn’t that wonderful?

• We were able to use the class Time, without having any idea about how it was implemented

• Now, let’s see what that class Time might actually look like inside

class Time {

private int _hour, _minute;

public Time (int h, int m) {_hour = h; _minute = m; }

public Time addMinutes (int m) { int totalMinutes = ((60*_hour)

+ _minute + m) % (24*60); if (totalMinutes < 0)

totalMinutes =totalMinutes + (24*60);

return new Time(totalMinutes/60,totalMinutes%60);

}

CONTINUED ON NEXT SLIDE

public void printTime ( ) { if ((_hour == 0) && (_minute == 0))

System.out.print(“midnight”); else if ((_hour == 12) && (_minute == 0))

System.out.print(“noon”); else {

if (_hour == 0) System.out.print(12);else if (_hour>12) System.out.print(_hour-12);else System.out.print(_hour);

if (_minute < 10) System.out.print(“:0”+_minute);else System.out.print(“:” + _minute);

if (_hour < 12) System.out.print(“AM”);else System.out.print(“PM”);

}}

} end of class Time

7- 79

private int _hour, _minute;

• Declares two integer attributes for objects created from class Time

• The modifier “private” means that the instance variables _hour and _minute can be used by methods inside the class Time (i.e., by objects that have those methods); they are not usable outside the class

7- 80

private int _hour, _minute;

• The modifier “public” would mean the variables could be accessed and modified by methods outside the class

• Good object oriented programming makes instance variables private; a well-designed program should rarely need public instance variables

7- 81

Constructors

• Constructors tell Java how to initialize new objects of the class

• It’s a method, but a special one

–Has the same name as the class

–Has no return type (not even void)

• Constructors are declared private or public (usually public, of course)

• Often takes arguments that are used in initializing the object

public Time (int h, int m) { _hour = h; _minute = m; }

7- 82

Method Definitions

• Definition headers tell what the method returns, and what its arguments are

• Both are declared public, meaning they can be called by clients of the class

• A class must have some public methods; often all the methods and the constructor are public, but if you want a method that will only be used internally to objects of the class, you can declare such a method private

public Time addMinutes (int m) { … }public void printTime ( ) { … }

7- 83

Using Your OwnInstance Variables

Notice that when a method, like addMinutes( ) or the Time( ) constructor, wants to use its own instance variables (_hour and _minute), it can just mention their names (no object necessary)

class Time {private int _hour, _minute;

public Time (int h, int m) { _hour = h; _minute = m; }

public Time addMinutes (int m) { int totalMinutes =((60*_hour) +_minute + m)%(24*60); if (totalMinutes < 0)

totalMinutes = totalMinutes + (24*60); return new Time(totalMinutes/60, totalMinutes%60);}

7- 84

Overloaded Constructors

• Sometimes its useful to be able to create new objects in multiple ways (using different numbers or types of arguments to the constructor)

• Java allows you to define multiple constructors, as long as you give them different numbers or types of arguments in the definitions (so Java will know which one you meant)

7- 85

Example of Additional Constructors

class Time {

private int _hour, _minute;

public Time (int h, int m) { _hour = h; _minute = m; }

public Time ( ) { _hour = 0; _minute = 0; }

public Time (int m) { _hour = m/60; _minute = m%60; }

public Time addMinutes (int m) { … }

public void printTime ( ) { … }

}

7- 86

How to Use Them

• With these new constructors, the declarations: Time t1 = new Time( ),

t2 = new Time(720),t3 = new Time(525);

are equivalent to:

Time t1 = new Time(0, 0),t2 = new Time(12, 0),t3 = new Time(8, 45);

7- 87

One Method Calling Another Method Inside the Same Object

• Let’s create a new method to put into the Time class

• Let’s call it subMinutes, where

bill.subMinutes(i)

gives the same results as

bill.addMinutes(-i)

7- 88

Implement by Using addMinutes( )

public Time subtractMinutes (int m) {return receiverobject.addMinutes(-m);

}

• Who is the receiverobject? When we’re defining the method in the class, we don’t yet know who the object is

• Like in the robot world, the receiver can be left out, and the object “talks to itself”

7- 89

But who is the “move” a Message To?

The messages will be sent by an instance of the MileWalker class to itself!

class MileWalker extends BasicRobot {

void moveMile {move;move;move;move;move;move;move;move;

}

}Remember?

7- 90

subtractMinutes( )

public Time subtractMinutes (int m) {return addMinutes(-m);

}

• bill is an object of type Time• client sends bill.subtractMinutes(n)• subtractMinutes( ) generates a

message to bill of addMinutes(-n)

7- 91

bill = bill.subtractMinutes(18);

bill

billAttributes: _hour = 13 _minute = 30Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

subtractMinutes(18)

7- 92

subtractMinutes(18) generates a message addMinutes(-18)

bill

billAttributes: _hour = 13 _minute = 30Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

addMinutes(-18)

7- 93

bill’s addMinutes( ) MethodCreates a New Time Object

bill

(it still has no name since it isn’t assigned to any variable)

billAttributes: _hour = 13 _minute = 30Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

Attributes: _hour = 13 _minute = 12Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

7- 94

Then This New Object is Assigned to the Time Variable bill

bill

Attributes: _hour = 13 _minute = 30Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

Attributes: _hour = 13 _minute = 12Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

(the old Time object is thrown away, automatically)

bill

7- 95

Let’s put another methodinto the class Time

Compare two times to see whether the first is “prior to” the second (assuming they’re in the same day)

t2Attributes: _hour = h2 _minute = m2Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m) boolean priorTo (Time t)

Attributes: _hour = h1 _minute = m1Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m) boolean priorTo (Time t)

t1

?

<

True if h1 < h2, or h1 = h2 and m1 < m2

7- 96

We need to have access to hour and minute of both objects

public boolean priorTo (Time t) { return ((_hour < t’s hour) || ((_hour == t’s hour) && (_minute < t’s minute)));}

•There are two objects: a receiving object (that gets the priorTo( ) message), and the argument object (t)

•“_hour”, “_minute” are the receiving object’s hour and minute (simply uses the variables’ names)

•How do we get to the argument object’s _hour and _minute?

7- 97

Access to an Object’sInstance Variables

• Hey, wait a second!

• Those variables were private in the definition of the class Time!

• How can they be accessed by another object?

public boolean priorTo (Time t) { return ((_hour < t._hour) || ((_hour == t._hour) && (_minute < t._minute)));}

7- 98

Encapsulation is not Among Instances of Same Class

• Encapsulation is to protect programmers, and is thus between the code of different classes

• Sometimes object instances of the same class need to access each other’s “guts” (e.g., for state copying – if we want to create an identical instance of an object we have)

7- 99

private int _hour, _minute;

• The modifier “private” means that the instance variables _hour and _minute can be used by methods inside the class Time (i.e., by objects that have those methods); they are not usable outside the class

• A method of class C can see the instance variables of objects of type C other than the receiver, using dot notation

7- 100

One More Method to Put in the Class Time

• Let’s define boolean after(Time t), which gives the opposite of priorTo (kind of)

• The receiver object checks to make sure that the argument object t is later than the receiver

• What’s wrong with this?public boolean after (Time t) { return !priorTo(t);}

7- 101

Not Quite Right

public boolean after (Time t) { return !priorTo(t);}

• Above returns true if the two objects are equal (since priorTo( ) returns false in that case); we want after( ) to return false if the two objects are equal; so switch the objects:

public boolean after (Time t) { return t.priorTo( receiver of this message );}

7- 102

We need to refer to the object that received the message

• In subtractMinutes( ), we got around the problem by sending a message with no receiver specified

• This worked, as Java took the “current object” as the one who would get the message

• But now we need to send the name of the “current object” as an argument, and we don’t know what the object will be named (when we are defining the class Time)

7- 103

this

• Java gives us “this” as a variable within an instance method that refers to the actual object that receives the message

• It’s a variable, but it never needs to be declared (we just get it implicitly)

• Solution is:

public boolean after (Time t) { return t.priorTo(this);}

7- 104

What’s going on

public boolean after (Time t) { return t.priorTo(this);}

Attributes: _hour = 13 _minute = 30Methods: ...

Attributes: _hour = 13 _minute = 12Methods: ...

second

first

after(second)

priorTo(first)

7- 105

public boolean after (Time t) { return t.priorTo(this);}

When the Class is Defined, these names are not known

Attributes: _hour = 13 _minute = 30Methods: ...

Attributes: _hour = 13 _minute = 12Methods: ...

second

first

after(second)

priorTo(this)

“this” stands for “first”

the clientwrote “first.after(second)”

here is t

7- 106

The Structure of theTime Class Definition

class Time {

private int _hour, _minute;

public Time (int h, int m) {_hour = h; _minute = m;}

public Time addMinutes (int m) { ... }

public void printTime ( ) { ... }

public Time subtractMinutes (int m) {return addMinutes(-m);

}

public boolean priorTo (Time t) {return ((_hour < t._hour) ||

((_hour == t._hour) && (_minute < t._minute))); }

public boolean after (Time t) {return t.priorTo(this);

}}

constructor definition

declarations of class attributes

5 method definitions

7- 107

We’ve Seen HowNested Method Calls Work

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void g ( ) { System.out.println(“A!”); System.out.println(“B!”); System.out.println(“C!”); System.out.println(“D!”);}

void e ( ) {......obj.f( );...}

1 324

5

68 7

9

A key point is that Java remembers where it was, and resumes execution there when returning from a method call

7- 108

A Stack Handles Nesting

• Let’s improve the way we think about this nesting

• When method e( ) calls method f( ), which calls method g( ), we can think of a “stack of methods”

• Like putting a piece of paper on top of another piece on top of another piece... the topmost piece is the method being executed now, the others we’ll return to

• Each piece of paper holds the parameters and local variables

7- 109

Starting Execution in main( )

Method main( )

STACK

public static void main (String[ ] args) {.........obj.e();...}

top

7- 110

Call to method e( )

Method e( )Where we came from: main, line 4

Method main( )

STACK

void e ( ) {......obj.f( );...}

public static void main (String[ ] args) {.........obj.e();...}

top

7- 111

Executing method e( )

Method e( )Where we came from: main, line 4

Method main( )

STACK

void e ( ) {......obj.f( );...}

public static void main (String[ ] args) {.........obj.e();...}

top

7- 112

Call to method f( )

Method e( )Where we came from: main, line 4

Method main( )

STACK

Method f( )Where we came from: e, line 3

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void e ( ) {......obj.f( );...}

public static void main (String[ ] args) {.........obj.e();...}

top

7- 113

Executing method f( )

Method e( )Where we came from: main, line 4

Method main( )

STACK

Method f( )Where we came from: e, line 3

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void e ( ) {......obj.f( );...}

public static void main (String[ ] args) {.........obj.e();...}

top

7- 114

Call to method g( )

Method e( )Where we came from: main, line 4

Method main( )

STACK

Method f( )Where we came from: e, line 3

Method g( )Where we came from: f, line 4

top

void g ( ) { System.out.println(“A!”); System.out.println(“B!”); System.out.println(“C!”); System.out.println(“D!”);}

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void e ( ) {......obj.f( );...}

main (String[ ] args) {.........obj.e();...}

7- 115

Method g( ) finishes,the stack has its top removed

void g ( ) { System.out.println(“A!”); System.out.println(“B!”); System.out.println(“C!”); System.out.println(“D!”);}

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void e ( ) {......obj.f( );...}

main (String[ ] args) {.........obj.e();...}

Method e( )Where we came from: main, line 4

Method main( )

STACK

Method f( )Where we came from: e, line 3

top

7- 116

Method f( ) finishes,the stack has its top removed

void g ( ) { System.out.println(“A!”); System.out.println(“B!”); System.out.println(“C!”); System.out.println(“D!”);}

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void e ( ) {......obj.f( );...}

main (String[ ] args) {.........obj.e();...}

Method e( )Where we came from: main, line 4

Method main( )

STACK

top

7- 117

Method e( ) finishes,the stack has its top removed

void g ( ) { System.out.println(“A!”); System.out.println(“B!”); System.out.println(“C!”); System.out.println(“D!”);}

void f ( ) { System.out.println(“Hi there!”); System.out.println(“Nice weather!”); ... obj.g( ); System.out.println(“That was fun!”); System.out.println(“Time to move on!”);}

void e ( ) {......obj.f( );...}

main (String[ ] args) {.........obj.e();...}

Method main( )

STACK

top

7- 118

Variables are heldon the stack, too

• When we put items on the stack, we also write down–values of parameters

– local variables

• Let’s look at the class Schedule, to see how the program actually executes and keeps track of variables with the stack

7- 119

Executing Schedule

Method main( )

STACK

top

class Schedule {public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( );System.out.println(“

____________________”);start = start.addMinutes(30);

...}

}

args: ?start: ? heap

7- 120

Creation of Time object “start”

Method main( )

STACK

class Schedule {public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( );System.out.println(“

____________________”);start = start.addMinutes(30);

...}

}

args: ?start:

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

heap

top

7- 121

Sending object “start” the printTime() message

Method main( )

STACK

class Schedule {public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( );System.out.println(“

____________________”);start = start.addMinutes(30);

...}

}

args: ?start:

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

heap

Method printTime( )Came from: main, line 2this:

top

7- 122

printTime() finishes,the stack is popped

Method main( )

STACK

class Schedule {public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( );System.out.println(“

____________________”);start = start.addMinutes(30);

...}

}

args: ?start:

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

heap

top

7- 123

Later…the message addMinutes(30) is sent to “start”

Method main( )

STACK

args: ?start:

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

heap

Method addMinutes( )Came from: main, line 4this:m: 30totalMinutes: ?

public Time addMinutes (int m) {int totalMinutes = ((60*_hour) + _minute + m)

% (24*60);...

}

class Schedule {public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( );System.out.println(“ ____________________”);start = start.addMinutes(30);

...}

}

top

7- 124

addMinutes( ) initializes totalMinutes

Method main( )

STACK

args: ?start:

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

heap

Method addMinutes( )Came from: main, line 4this:m: 30totalMinutes: 540

class Schedule {public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( );System.out.println(“ ____________________”);start = start.addMinutes(30);

...}

}

public Time addMinutes (int m) {int totalMinutes = ((60*_hour) + _minute + m)

% (24*60);...

}

top

7- 125

addMinutes creates new Time object and returns it

Method main( )

STACK

args: ?start:

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

heap

class Schedule {public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( );System.out.println(“ ____________________”);start = start.addMinutes(30);

...}

}

Attributes: _hour = 9 _minute = 0Methods: Time addMinutes(int m) void printTime ( )

top

7- 126

main assignsreturned value to start

Method main( )

STACK

args: ?start:

Attributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

heap

class Schedule {public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( );System.out.println(“ ____________________”);start = start.addMinutes(30);

...}

}

Attributes: _hour = 9 _minute = 0Methods: Time addMinutes(int m) void printTime ( )

start

top

7- 127

Let’s Try it Again

What if we had the same program, but instead of the message addMinutes(30), we had the message subtractMinutes(10)?

class Schedule2 {public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( );System.out.println(“ ____________________”);start = start.subtractMinutes(10);

...}

}

7- 128

The message subtractMinutes(10) is sent to “start”

Method main( )

STACK

args: ?start:

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

heap

Method subtractMinutes()Came from: main, line 4this:m: 10

public Time subtractMinutes (int m) { return addMinutes(-m);

}

class Schedule2 {public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( );System.out.println(“ ____________________”);start = start.subtractMinutes(10);

...}

}

top

7- 129

subtractMinutes( ) generates anaddMinutes( ) message to the same object

Method main( )

STACK

args: ?start:

Method subtractMinutes()Came from: main, line 4this:m: 10

Method addMinutes( )Came from: subtractMinutes, line 1this:m: -10totalMinutes: ?

public Time addMinutes (int m) {int totalMinutes = ((60*_hour) + _minute + m)

% (24*60);...

}

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

heap

top

7- 130

addMinutes( ) initializes totalMinutes

public Time addMinutes (int m) {int totalMinutes = ((60*_hour) + _minute + m)

% (24*60);...

}

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

heap

Method main( )

STACK

args: ?start:

Method subtractMinutes()Came from: main, line 4this:m: 10

Method addMinutes( )Came from: subtractMinutes, line 1this:m: -10totalMinutes: 500

top

7- 131

addMinutes( ) creates new Time object and returns it to subtractMinutes( )

Method main( )

STACK

args: ?start:

Method subtractMinutes()Came from: main, line 4this:m: 10

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

heap

Attributes: _hour = 8 _minute = 20Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

top

7- 132

...which returns it to main( )...

Method main( )

STACK

args: ?start:

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

heap

Attributes: _hour = 8 _minute = 20Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

class Schedule2 {public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( );System.out.println(“ ____________________”);start = start.subtractMinutes(10);

...}

}

top

7- 133

…which assigns it to Time variable “start”

Method main( )

STACK

args: ?start:

Attributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

heap

Attributes: _hour = 8 _minute = 20Methods: Time addMinutes(int m) void printTime ( ) Time subtractMinutes(int m)

start

(garbage,thrown away)

class Schedule2 {public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( );System.out.println(“ ____________________”);start = start.subtractMinutes(10);

...}

}

top

7- 134

Call-by-value

• Parameters are passed into methods in Java in a straightforward way

• They are copied into the formal parameters of the method, like an assignment statement would do

• This kind of parameter passing is known as call-by-value

7- 135

Java passes parameters using call-by-value

bill.checkValue(3, 7, 9)

boolean checkValue (int col, int row, int limit) {if (row > limit)

...else

...}

col is assigned 3

row is assigned 7

limit is assigned 9

7- 136

Even When Simple Variables are Involved

• With call-by-value, col gets a copy of what's in x, row gets a copy of what's in y, limit gets a copy of what's in z

• Right after we return from checkValue, there's not going to have been any change to the values of x, y, z – guaranteed

x = 3;y = 7;z = 9;bill.checkValue(x, y, z);

boolean checkValue (int col, int row, int limit) {...

}

7- 137

Java passes parameters using call-by-value

• Nothing unusual seems to be happening here

• However, there are consequences of call-by-value, both for simple type parameters, as well as for object type parameters

• Let’s explore the issues

7- 138

I Can See Clearly Now

• If you understand what is going on with addresses, the operations in Java between object variables and during parameter passing become completely clear

• Ready?

7- 139

Start with Regular Assignment to a Simple Variable

• When we are dealing with simple variables, assignment takes the contents of the right-hand side and puts in the left-hand side variable:temperature = 98.6;totalMinutes = 43;days = totalMinutes;

[1247][1248][1249][1250][1251][1252][1253][1254]

undefinedundefinedundefinedundefined

43 43 98.6

totalMinutes temperaturedays

7- 140

Aliasing

• Two different variables can refer to the same object (we’ve seen this before); this is known as aliasingTime dawn, sunrise;dawn = new Time(5, 35);sunrise = dawn;

sunrise

Attributes: _hour = 5 _minute = 35Methods: …

dawn

7- 141

Time dawn, sunrise;dawn = new Time(5, 35);sunrise = dawn;

Aliasing

[1247][1248][1249][1250][1251][1252][1253][1254]

undefinedundefined

43 12 98.6

totalMinutes temperaturedays

dawn

Attributes: _hour = 5 _minute = 35Methods: …

heap

sunrise

29427

2942729427

7- 142

Time dawn, sunrise;dawn = new Time(5, 35);sunrise = dawn;

I Can Draw It This Way

[1247][1248][1249][1250][1251][1252][1253][1254]

undefinedundefined

43 12 98.6

totalMinutes temperaturedays

dawn

Attributes: _hour = 5 _minute = 35Methods: …

heap

sunrise

7- 143

Any operation that changes one alias also affects the other one

• Let’s say we change the dawn object; then the sunrise object is also affected (since it’s the same object); we'll define "advanceMinutes()" later:dawn.advanceMinutes(70); //change object's attributes

sunrise

Attributes: _hour = 6 _minute = 45Methods: …

dawn

7- 144

Aliasing

[1247][1248][1249][1250][1251][1252][1253][1254]

undefinedundefined

43 12 98.6

totalMinutes temperaturedays

dawn

Attributes: _hour = 6 _minute = 45Methods: …

heap

sunrise

29427

2942729427

dawn.advanceMinutes(70);

7- 145

Time dawn, sunrise;dawn = new Time(5, 35);sunrise = dawn;dawn.advanceMinutes(70); // change object's attributes sunrise.printTime( ); // prints 6:45AM

The Effect

sunrise

Attributes: _hour = 6 _minute = 45Methods: …

dawn 29427

29427

29427

heap

7- 146

The Effect

sunrise

Attributes: _hour = 6 _minute = 45Methods: …

dawn

Time dawn, sunrise;dawn = new Time(5, 35);sunrise = dawn;dawn.advanceMinutes(70); // change object's attributes sunrise.printTime( ); // prints 6:45AM

7- 147

What Does This Mean for Parameter Passing?

• In Java, arguments are copied into formal parameters of a method

• For simple types (like int and double), this means that the method has only a copy of the original variable

• For object types, this means that the method has a copy of the reference to, i.e., the address of, the original object (and can mutate the original object)

7- 148

Example: Original Definition of addMinutes( )

public Time addMinutes (int m) { int totalMinutes = ((60*_hour)+ _minute + m)%(24*60); if (totalMinutes < 0)

totalMinutes = totalMinutes + (24*60); return new Time(totalMinutes/60, totalMinutes%60);}

Calculation of totalMinutes is done within the method.

7- 149

New Definition of addMinutes( )

Calculation of totalMinutes is done outside of addMinutes( ), inside calculate( ). We want calculate( ) to change the value of totalMinutes. It doesn’t happen.

public Time addMinutes (int m) {int totalMinutes;

calculate(totalMinutes, m); return new Time(totalMinutes/60, totalMinutes%60);}

public void calculate(int total, int i) { total = ((60*_hour) + _minute + i) % (24*60); if (total < 0) total = total + (24*60);}

7- 150

public Time addMinutes (int m) {int totalMinutes;calculate(totalMinutes, m);return new Time(totalMinutes/60, totalMinutes%60);

}

public void calculate(int total, int i) {total = ((60*_hour) + _minute + i) % (24*60);if (total < 0)

total = total + (24*60);}

Example:What’s Happening on the Stack?

Method main( )

STACK

args: ?start:

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

heap

Method addMinutes( )Came from: main, line 4this:m: 30totalMinutes: ?

top

7- 151

Now we call calculate( )

Method main( )

STACK

args: ?start:

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

heap

Method addMinutes( )Came from: main, line 4this:m: 30totalMinutes: ?

Method calculate( )Came from: addMinutes, line 2this:i: 30total: ?

totalMinutes had no value at the time of the call, so total has no starting value

top

7- 152

calculate( ) assigns a value to total

Method main( )

STACK

args: ?start:

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

heap

Method addMinutes( )Came from: main, line 4this:m: 30totalMinutes: ?

Method calculate( )Came from: addMinutes, line 2this:i: 30total: 540

total now has a value, but totalMinutes still has none

top

7- 153

calculate( ) returns nothing to addMinutes( )

Method main( )

STACK

args: ?start:

startAttributes: _hour = 8 _minute = 30Methods: Time addMinutes(int m) void printTime ( )

heap

Method addMinutes( )Came from: main, line 4this:m: 30totalMinutes: ?

totalMinutes still has no value; addMinutes( ) will not work correctly

top

7- 154

Bottom Line, call-by-value:total is just a copy of totalMinutes

Since total is just a copy of totalMinutes, changes made to total do not cause changes to totalMinutes

public Time addMinutes (int m) {int totalMinutes;

calculate(totalMinutes, m); return new Time(totalMinutes/60, totalMinutes%60);}

public void calculate(int total, int i) { total = ((60*_hour) + _minute + i) % (24*60); if (total < 0) total = total + (24*60);}

7- 155

Something Similar When Objects are Passed as Arguments

public Time addHours (Time t, int m) { advanceBy(t, m*60); return t;}

public void advanceBy(Time theNewTime, int m) { theNewTime = theNewTime.addMinutes(m);}

In advanceBy( ), a new Time object is generated and assigned to theNewTime. This does not affect the value of t in addHours( ).

7- 156

One Solution, to Get t Changed

public Time addHours (Time t, int m) { t = advanceBy(t, m*60); return t;}

public Time advanceBy(Time theNewTime, int m) { theNewTime = theNewTime.addMinutes(m);

return theNewTime;}

7- 157

First Solution, Shorter

public Time addHours (Time t, int m) { return advanceBy(t, m*60);}

public Time advanceBy(Time theNewTime, int m) { return theNewTime.addMinutes(m);

}

7- 158

Second Solution,to Get t Changed

public Time addHours (Time t, int m) { advanceBy(t, m*60); return t;}

public void advanceBy(Time theNewTime, int m) { theNewTime.advanceMinutes(m);

}

We'll look at advanceMinutes() again later.

7- 159

What it Looks Like, when advanceBy( ) is called

heap

Method main( )

STACK

args: ?start:

Method addHours()Came from: main, line 8this:m: 2t:

Method advanceBy( )Came from:addHours, line 1this:m: 120theNewTime:

startAttributes: Methods:

_hour = 8 ... _minute = 30

Attributes: Methods:

_hour = 13 ... _minute = 45

t, theNewTime

7- 160

What it Looks Like, after advanceBy( ) calls addMinutes( )

heap

Method main( )

STACK

args: ?start:

Method addHours()Came from: main, line 8this:m: 2t:

Method advanceBy( )Came from:addHours, line 1this:m: 120theNewTime:

startAttributes: Methods:

_hour = 8 ... _minute = 30

Attributes: Methods:

_hour = 13 ... _minute = 45

t, theNewTime

Attributes: Methods:

_hour = 15 ... _minute = 45

7- 161

What it Looks Like, at the end of advanceBy( ); theNewTime is changed, but not t

heap

Method main( )

STACK

args: ?start:

Method addHours()Came from: main, line 8this:m: 2t:

Method advanceBy( )Came from:addHours, line 1this:m: 120theNewTime:

startAttributes: Methods:

_hour = 8 ... _minute = 30

Attributes: Methods:

_hour = 13 ... _minute = 45

t

Attributes: Methods:

_hour = 15 ... _minute = 45

theNewTime

7- 162

Call-by-valuefor Object Arguments

• When we passed the value of t into theNewTime, we were passing a reference to an object, not the object itself

• At the start of advanceBy( ), both t and theNewTime were pointing at the same object in the heap

• If advanceBy( ) had actually changed the object, rather than just generating a new one, then t would have been affected, too

7- 163

If advanceBy( ) had changed theNewTime’sobject, t’s object would have been changed

heap

Method main( )

STACK

args: ?start:

Method addHours()Came from: main, line 8this:m: 2t:

Method advanceBy( )Came from:addHours, line 1this:m: 120theNewTime:

startAttributes: Methods:

_hour = 8 ... _minute = 30

Attributes: Methods:

_hour = 13 ... _minute = 45

t, theNewTime

7- 164

Variable Scope

• What happens if you use the same name for an instance variable, a formal parameter, and a local variable?

• It’s illegal to use the same name for a formal parameter of a method and a local variable in the same method

• It is all right to use the same name for an instance variable and either a formal parameter or local variable

7- 165

Legal Use of Variable x

class C {int x;...

void f (String y) {

double x;...… x ...

}}

instance variable called x; by convention, we would normally write “_x”

This x refers to the local variable

local variable called x

7- 166

Formal Parameter x

class C {int x;...

void f (double x) {

...

...… x ...

}}

instance variable called x; by convention, we would normally write “_x”

This x refers to the formal parameter

formal parameter called x

7- 167

Scope of Variables in Java

• The scope of a variable is the part of a program in which that variable can be referenced

• The scope of a formal parameter or local variable is the body of its method

• The scope of an instance variable is its entire class, except where there is a formal parameter or local variable of the same name; that creates a “hole” in its scope

7- 168

Hole in the scope ofinstance variable x

class C {int x;...void f (double x)

{…

}

void g (int y) {…

} }

scope ofinstance

variable x

hole in

scope

7- 169

Using “this” to reference a hidden variable

class C {int x;…void f (double x)

{… x …… this.x …

}

void g (int y) {…

} }

This x refers to the formal parameter

This x refers to the instance

variablefor the class C

instance variable called x; by convention, we would normally write “_x”

7- 170

Changing Attribute Values:Mutability

• The Time class, as we’ve defined it so far, never has its attributes changed

• The constructor of a Time object assigns values to its attributes

• Nothing can change those attributes (no methods exist to do it, no outside assignment can do it)

• The Time class is an immutable class or immutable type

7- 171

Things Don’t Have to Be This Way

• Methods are allowed to change instance variables by assignment

• This is, in fact, a very common and useful thing for objects to be able to do to themselves, in response to a message

• Such methods are called mutating operations

• A class that has such methods is called a mutable class or mutable type

7- 172

Let’s Make Time a Mutable Class

• We’ll add the following mutating operation on the Time class (similar to addMinutes, but addMinutes left the Time object unchanged):public void advanceMinutes (int m) { int totalMinutes =

((60*_hour) + _minute + m) % (24*60); if (totalMinutes < 0)

totalMinutes = totalMinutes + (24*60); hour = totalMinutes / 60; minute = totalMinutes % 60;}

The 2 mutating assignments

7- 173

Consider the Following Example

Time lunchtime = new Time(12, 0),dinnertime = new Time(0, 0);

lunchtime.printTime( ); // prints: noonlunchtime.advanceMinutes(10);lunchtime.printTime( ); // prints: 12:10PMdinnertime = lunchtime.addMinutes(6 * 60);lunchtime.printTime( ); // still prints: 12:10PM

dinnertime.printTime( ); // prints: 6:10PM

7- 174

Creation of Two New Objects

Time lunchtime = new Time(12, 0),dinnertime = new Time(0, 0);

lunchtime

lunchtimeAttributes: _hour = 12 _minute = 0Methods: …

dinnertime

dinnertimeAttributes: _hour = 0 _minute = 0Methods: …

7- 175

lunchtime.advanceMinutes(10);

advanceMinutes(10)

lunchtime

lunchtimeAttributes: _hour = 12 _minute = 0Methods: …

dinnertime

dinnertimeAttributes:

_hour = 0_minute = 0

Methods:…

7- 176

The result of the advanceMinutes(10) message

lunchtime

lunchtimeAttributes: _hour = 12 _minute = 10Methods: …

dinnertime

dinnertimeAttributes:

_hour = 0_minute = 0

Methods:…

7- 177

lunchtime.addMinutes(6 * 60)

addMinutes(6 * 60)

lunchtime

lunchtimeAttributes: _hour = 12 _minute = 10Methods: …

dinnertime

dinnertimeAttributes:

_hour = 0_minute = 0

Methods:…

7- 178

The result of theaddMinutes(6 * 60) message

lunchtime

lunchtimeAttributes: _hour = 12 _minute = 10Methods: …

Attributes: _hour = 18 _minute = 10Methods: …

dinnertime

dinnertimeAttributes:

_hour = 0_minute = 0

Methods:…

7- 179

dinnertime = lunchtime.addMinutes(6 * 60);

lunchtime

lunchtimeAttributes: _hour = 12 _minute = 10Methods: …

Attributes: _hour = 18 _minute = 10Methods: …

dinnertime

garbage

dinnertime

dinnertimeAttributes:

_hour = 0_minute = 0

Methods:…

7- 180

Methods that return values are expressions; methods that are void are statements

• It is illegal to write:lunchtime = lunchtime.advanceMinutes(10);

• Why?

• It is illegal to write:lunchtime.addMinutes(10);

• Why?A void method suggests that it is a mutating operation; a method with a return value suggests it is not a mutating operation, but not for sure.

7- 181

Mutable vs. Immutable Classes(another way of saying it)

• For an immutable class C, the value of the object being pointed to by a variable of type C (like “bill”) can be changed only by an assignment statement:bill = …

• For a mutable class, the value of the object being pointed to by a variable of type C (like “dinnertime” or “lunchtime”) can be changed either by assignment or by sending the right message:dinnertime = lunchtime.addMinutes(6 * 60);lunchtime.advanceMinutes(10);

7- 182

public void advanceMinutes (int m) { int totalMinutes = ((60*_hour) + _minute + m) % (24*60); if (totalMinutes<0) totalMinutes=totalMinutes + (24*60); hour = totalMinutes / 60; minute = totalMinutes % 60;}

public Time addMinutes (int m) { int totalMinutes = ((60*_hour) +_minute + m)%(24*60); if (totalMinutes < 0)

totalMinutes = totalMinutes + (24*60); return new Time(totalMinutes/60, totalMinutes%60);}

Review:addMinutes vs. advanceMinutes

• addMinutes generates new Time object

• advanceMinutes mutates original Time object

7- 183

Review: Passing a Reference to an Object as an Argument

public Time addHours (Time t, int m) { advanceBy(t, m*60); return t;}

public void advanceBy(Time theNewTime, int m) { theNewTime = theNewTime.addMinutes(m);}

In advanceBy( ), a new Time object is generated and assigned to theNewTime. This does not affect the value of t in addHours( ).

7- 184

Review: What it Looks Like, at the end of advanceBy( ); theNewTime (object) is changed, but not t (object)

heap

Method main( )

STACK

args: ?start:

Method addHours()Came from: main, line 8this:m: 2t:

Method advanceBy( )Came from:addHours, line 1this:m: 120theNewTime:

startAttributes: Methods:

_hour = 8 ... _minute = 30

Attributes: Methods:

_hour = 13 ... _minute = 45

t

Attributes: Methods:

_hour = 15 ... _minute = 45

theNewTime

7- 185

Now, what if instead we called a mutating method?

public Time addHours (Time t, int m) { advanceBy(t, m*60); return t;}

public void advanceBy(Time theNewTime, int m) { theNewTime.advanceMinutes(m);}

In advanceBy( ), the original object (pointed to by both t and theNewTime) is now changed. This does affect the value of t’s object in addHours( ).

7- 186

What it Now Looks Like, at the end of advanceBy( ); theNewTime (object) is changed, and so is t (object)

heap

Method main( )

STACK

args: ?start:

Method addHours()Came from: main, line 8this:m: 2t:

Method advanceBy( )Came from:addHours, line 1this:m: 120theNewTime:

startAttributes: Methods:

_hour = 8 ... _minute = 30

Attributes: Methods:

_hour = 15 ... _minute = 45

t, theNewTime

7- 187

What it Now Looks Like, at the end of advanceBy( ); theNewTime (object) is changed, and so is t (object)

heap

Method main( )

STACK

args: ?start: 2196

Method addHours()Came from: main, line 8this: 2196 m: 2t: 19364

Method advanceBy( )Came from:addHours, line 1this: 2196m: 120theNewTime: 19364

startAttributes: Methods:

_hour = 8 ... _minute = 30

Attributes: Methods:

_hour = 15 ... _minute = 45

t, theNewTime

2196

19364

7- 188

From C to Shining C

• In Java, even though an object variable is (in fact) a number (i.e., an address), you cannot add to it, subtract from it, or use its value! You can:–Send a message to the object the variable

addresses–Assign an object variable’s value to

another object variable (so they address the same location), i.e., “dawn = sunrise;”

7- 189

Object Oriented Programming

• Objects in the computer are supposed to correspond to objects in the real world

• “The basic idea of object-oriented programming is that programs manipulate objects that correspond to objects in the real world”

7- 190

Creating a Class

• In creating classes to mimic the real world system, we need to decide on:–The appropriate objects

–Their interfaces, which will be known to the outside users of our objects

–The internal representation for the objects (implementing the objects)

• The representation affects how easy it will be to program the methods and how efficient the methods will be

7- 191

Six Examples

• Checkers Game

• Chess Game

• Address Book

• Date Book

• Simulation of Football

• Simulation of Baseball

Consider the class definitions and interfaces that would allow a client to create programs.

7- 192

Clients and Classes

• In examples I give, I sometimes just present the client, and sometimes just present the classes it uses. Of course, the client is a class, too, the one with the primary method main( ).

• The complete system consists of both:class Schedule {

public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( );System.out.println(“ ____________________”);start = start.addMinutes(30);

start.printTime( );System.out.println(“ ____________________”);start = start.addMinutes(30);

start.printTime( );System.out.println(“ ____________________”);start = start.addMinutes(30);

start.printTime( );System.out.println(“ ____________________”);}

}

client, e.g., Schedule

class Time {

private int hour, minute;

public Time (int h, int m) { hour = h; minute = m; }

public Time addMinutes (int m) { ... }

public void printTime ( ) { ... }

public Time subtractMinutes (int m) {return addMinutes(-m);

}

public boolean priorTo (Time t) {return ((hour < t.hour) | |

((hour == t.hour) && (minute < t.minute)));}

public boolean after (Time t) {return t.priorTo(this);

}}

class, e.g., Time

7- 193

Example: A Tic-Tac-Toe Board

• Let’s create a class to represent the tic-tac-toe board

• It’s an important object in the game

• It needs to have a place to store the X’s and O’s, and should provide methods for placing them, and for asking if a location has an X, an O, or is blank

• It might also keep track of whose move is next, and whether someone has won

7- 194

Different alternatives

• Let’s consider various alternatives

• Let’s assume the following numbering scheme:

1 2 3

4 5 6

7 8 9

• The first thing is to decide on the board’s interface — what methods it has and what they do

7- 195

One Possibility

• For a TTTBoard object:

boolean isMarked (int square)int getMark (int square)void putO (int square)void putX (int square)

• getMark returns the mark (if any in a given square); returns 0 for O, 1 for X, 2 otherwise

1 2 3

4 5 6

7 8 9

7- 196

What About “Erroneous” Actions?

• In case the client passes a number outside 1 to 9, the methods do the following:isMarked: returns falsegetMark: returns 2putO: do nothing, leave board unchangedputX: do nothing, leave board unchanged

• With putO and putX, if the client asks to put a mark on an occupied square, the request is ignored and the board is unchanged

7- 197

Division of Labor, client and class

• In general, there is a trade-off between the work that is done by the client and that done by the object itself

• Sometimes we can make the class do more work, and save the client work, and vice versa

• It’s a design decision when the system is built

7- 198

Now We are Talking about the Class, used by the Client

• For the tic-tac-toe board, what will the class definition look like?

class Schedule {public static void main (String[ ] args) {

Time start = new Time(8, 30);

start.printTime( );System.out.println(“ ____________________”);start = start.addMinutes(30);

start.printTime( );System.out.println(“ ____________________”);start = start.addMinutes(30);

start.printTime( );System.out.println(“ ____________________”);start = start.addMinutes(30);

start.printTime( );System.out.println(“ ____________________”);}

}

client, e.g., Player

class Time {

private int hour, minute;

public Time (int h, int m) { hour = h; minute = m; }

public Time addMinutes (int m) { ... }

public void printTime ( ) { ... }

public Time subtractMinutes (int m) {return addMinutes(-m);

}

public boolean priorTo (Time t) {return ((hour < t.hour) | |

((hour == t.hour) && (minute < t.minute)));}

public boolean after (Time t) {return t.priorTo(this);

}}

class, e.g., TTTBoard

7- 199

The Structure of theTTTBoard Class Definition

class TTTBoard {

instance variables;

public TTTBoard ( ) {initialize empty board … }

public boolean isMarked (int square) {…}

public int getMark (int square) {…}

public void putO (int square) {…}

public void putX (int square) {…}

}

constructor definition

declarations of class attributes

4 method definitions

7- 200

Representation

• Now, let’s decide on a representation for the squares on the board

• We could use a variable for each square, which contains zero for O, one for X, and 2 if it is empty

• (This is a common technique, to use an otherwise unused value to mean “empty” or “undefined”)

class TTTBoard {

private int _sq1, _sq2, _sq3, _sq4, _sq5,_sq6, _sq7, _sq8, _sq9;

// Each square contains 2 if empty,// 0 for O, 1 for X

public TTTBoard ( ) {_sq1 = 2; _sq2 = 2; _sq3 = 2;_sq4 = 2; _sq5 = 2; _sq6 = 2;_sq7 = 2; _sq8 = 2; _sq9 = 2;

}

public boolean isMarked (int square) {...}

public int getMark (int square) {...}

public void putO (int square) {...}

public void putX (int square) {...}

}

7- 202

One of the Methods(the rest are similar)

public boolean isMarked (int square) { switch (square) {

case 1: return (_sq1 != 2); case 2: return (_sq2 != 2); case 3: return (_sq3 != 2); case 4: return (_sq4 != 2); case 5: return (_sq5 != 2); case 6: return (_sq6 != 2); case 7: return (_sq7 != 2); case 8: return (_sq8 != 2); case 9: return (_sq9 != 2); default: return false;} Why no break

statements?

7- 203

Changing the Implementation of a Class

• Encapsulation allows us to change an implementation of a class without affecting other parts of the program.

• Without encapsulation changes to implementation might “break” the program – many changes

• Why would we want to change the implementation?

–Different implementations have different tradeoffs (e.g., space conservation, efficiency etc.)

7- 204

We Could Use a Completely Different Internal Representation

• Let’s say we wanted the methods of TTTBoard to be shorter

• Let’s change the representation of the board, so that instead of using 9 separate instance variables, we’ll use a single integer to represent the whole board

• The largest possible integer in Java is 2,147,483,647

7- 205

A Single int for the Whole Board

• Ones digit is square 1, tens digit is square 2, hundreds digit is square 3, etc.

1 2 3

4 5 6

7 8 9

9’s, 8’s, 7’s, 6’s, 5’s, 4’s, 3’s, 2’s, 1’s

7- 206

A Single int for the Whole Board

• So here is one example, with (as usual) 0 for O, 1 for X, and 2 for empty

X X

O

O X

120,220,211position 1position 9

let’s call thisprivate int variable“_boardSquares”

1 2 3

4 5 6

7 8 9

7- 207

Simple Formula

• Given this representation, the contents of square s in board B is

(B/10s - 1) mod 10

• The division throws away the s - 1 digits to the right of the s position, then the mod 10 throws away the remaining digits to the left of the s position

7- 208

New isMarked( ) Method

public boolean isMarked (int square) { if (square < 1 || 9 < square)

return false; else

return ((_boardSquares / (int) Math.pow(10, square-1))%10) != 2;

}

Math.pow computes xy for doubles x and y.

7- 209

New TTTBoard2 Constructor and New getMark( )

public TTTBoard2 ( ) {_boardSquares = 222222222;

}

public int getMark (int square) { if (square < 1 || 9 < square)

return 2; else

return (_boardSquares /(int) Math.pow(10,square-1)) % 10;

}

7- 210

Some Things Get Trickier

• To place a mark in a square:–The square must be unoccupied (i.e., contain a 2)

–Then the 2 must be removed and replaced with a 0 or a 1

B - (2 * 10s-1), to place an OB - (2 * 10s-1) + 10s-1, to place an X{change B to

But the interfaces of putO and putX are still unchanged

7- 211

New putO( )

public void putO (int square) { if (square < 1 || 9 < square)

return; if (isMarked(square))

return; _boardSquares = _boardSquares -

(int) (2 * Math.pow(10, square-1));}

7- 212

New putX( )

public void putX (int square) { if (square < 1 || 9 < square)

return; if (isMarked(square))

return; _boardSquares = _boardSquares -

(int) (Math.pow(10, square-1));}

7- 213

Representation Independence

• Notice that changing the representation in these cases did not change the interface

• This is called “representation independence”, and is an important feature in using Java classes

• Using the private keyword is an important part of this feature

7- 214

What if the Client Wrote the Following?

TTTBoard board1 = new TTTBoard( );

if (board1._sq1 == 2)

System.out.println(“Square 1 is unoccupied”);

• The client gets an error message:“No variable _sq1 defined in class TTTBoard”

• This happens because our instance variables (in both representations) are declared as private

• If they had been declared public, then this would have worked with the first representation, and not worked with the second representation

• Terrible! Unacceptable! Bad for large programs!

7- 215

Interface and Representation

• Sometimes, changing the interface can force a change in the representation (e.g., having the board enforce alternating moves)

• See the Mickunas book for more examples

• None of these representations is very good (e.g., they are not extensible to larger boards, more dimensions)

7- 216

An Interface Change that Requires a Change in Representation

class TTTBoard3 {private int _boardSquares;private boolean _xMovesNext;

public TTTBoard3 ( ) {_boardSquares = 222222222;_xMovesNext = true;

}

public boolean isMarked (int square) {…}public int getMark (int square) {…}public void putO (int square) {…}public void putX (int square) {…}

}

7- 217

Another new putO( )

public void putO (int square) { if (_xMovesNext) { System.out.println(“Attempted move out of turn”); return; } if (square < 1 || 9 < square) return; if (isMarked(square)) return; _boardSquares = _boardSquares -

(int) (2 * Math.pow(10, square-1)); _xMovesNext = true;}

7- 218

Another new putX( )

public void putX (int square) { if (!_xMovesNext) {

System.out.println(“Attempted move out of turn”);return;

} if (square < 1 || 9 < square)

return; if (isMarked(square))

return; _boardSquares = _boardSquares -

(int) (Math.pow(10, square-1)); _xMovesNext = false;}