Learning Objects for Methods
Concept Methods are the simplest construct for abstraction in Java. A method starts with a declaration that defines its signature: the name of the method, the number and types of the formal parameters and the return type. The body of the method consists of local variable declarations and of statements. A method is called or invoked by writing the name of the method followed by a list of values, called actual parameters, one for each formal parameter. A method can return a value or it can be declared as
void if no value is returned.These source code of these learning objects can be found in method.zip.
| LO | Topic | Java Files (.java) | Prerequisites |
| "A void method" | A void method | Method01 | |
| "A method returning a value" | A method returning a value | Method02 | |
| "Calling one method from another" | Calling one method from another | Method03 | 1, 2 |
| "Recursion" | Recursion | Method04 | 2 |
| "Calling methods on an object" | Calling methods on an object | Method05 | 2, * |
| "Calling a method on the same object" | Calling a method on the same object | Method06 | 5, * |
| "Objects as parameters" | Objects as parameters | Method07 | 5, * |
| "Returning objects" | Returning objects | Method08 | 7, * |
| "Returning locally instantiated objects" | Returning locally instantiated objects | Method09 | 8, * |
* This LO assumes knowledge of the declaration of classes and the instantiation of objects.
A void method
Concept When a method that is declared
void is called, it allocates memory for its parameters and local variables, executes its statements and then returns. The call is a statement constructed from the name of the method followed by a list of actual parameters.Program: Method01.java
// Learning Object Method01
// void methods
public class Method01 {
static void printMax(int a, int b) {
int max;
if (a > b)
max = a;
else
max = b;
System.out.println(max);
}
public static void main(/*String[] args*/) {
int x = 10, y = 20;
printMax(x, y);
Method01.printMax(10, y);
}
}
The program computes the maximum of two integer values.
- The variables
xandyare allocated and initialized. - The method is called with the values of the actual parameters
xandy. - Memory is allocated for the formal parameters of the method and the local variables. This is called an activation record and is displayed by Jeliot in the upper left hand part of the screen labeled
Method Area. The new activation record hides the previous ones which are no longer accessible. - The actual parameters are used to initialize the formal parameters in the activation record.
- The local variable
maxis allocated within the activation record. - The statements of the method are executed.
- After the last statement has been executed, the method returns and the activation record is deallocated.
- Execution continues with the statement after the method call. Here, the method is called again, this time with an integer literal as an actual parameter instead of a variable.
Note: In a call to a static method, the name of the class in which it is defined can be given as in the second call. Since the method is defined in the same class as the call, the class name need not be given, as shown in the first call.
Exercise Trace the execution of a call of the following method and explain why it doesn't swap the values of the actual parameters.
void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
Can you write a method to swap two integer values?
A method returning a value
Concept When a method that is declared with a return type is called, it allocates memory for its parameters and local variables, executes its statements and then returns a value of the type. The call is a statement constructed from the name of the method followed by a list of actual parameters; the call is an expression and can appear wherever an expression is allowed.
Program: Method02.java
// Learning Object Method02
// methods returning a value
public class Method02 {
static int maximum(int a, int b) {
if (a > b)
return a;
else
return b;
}
public static void main(/*String[] args*/) {
int x = 10, y = 20;
int max;
max = maximum(x, y);
System.out.println(max);
}
}
- The variables
xandyare allocated and initialized; the variablemaxis allocated but not initialized. - An assignment statement is executed: the expression on the right hand side is a method call including the values of the actual parameters
xandy. - Memory is allocated for the formal parameters of the method and the local variables. This is called an activation record and is displayed by Jeliot in the upper left hand part of the screen labeled
Method Area. The new activation record hides the previous ones which are no longer accessible. - The actual parameters are used to initialize the formal parameters in the activation record.
- The statements of the method are executed.
- When the statement
return bis executed, the value ofbis used for the value to be returned. - The method returns and the activation record is deallocated.
- The value returned becomes the value of the expression assigned to the variable
max. - The value of
maxis printed.
Exercise Write the body of the main method as one statement.
Calling one method from another
Concept One method can call another, that is, when executing one method, any statement or expression call be a method call. A sequence of method calls results in a stack of activation records, where each method (except the last one that was called) is waiting for the method it called to return. There is no limit on the depth of method calls, except of course the amount of memory allocated to the program.
Note: The
main method is a method like any other. The operating system can be considered as a program which calls the main method. This call has a single parameter: an array of strings containing the contents of the command line.Program: Method03.java
// Learning Object Method03
// calling a method from a method
public class Method03 {
static int maximum(int a, int b) {
if (a > b)
return a;
else
return b;
}
static void printMax(int a, int b) {
int max;
max = Method03.maximum(a, b);
System.out.println(max);
}
public static void main(/*String[] args*/) {
printMax(10, 20);
}
}
- The
mainmethod calls the methodprintMax; the actual parameters are two integer literals. - The activation record for
printMaxis allocated, and the actual parameters are used to initialize the formal parametersaandb. - The variable
maxis allocated but not initialized. - The method
maximumis called; the actual parameters are the values ofaandb, which are the formal variables of methodprintMax. - An activation record is allocated for
maximum. (There are now three activation in the stack.) The new activation record includes memory for the formal parametersaandb; note that these are new parameters not at all related to the formal parameters of the same names in the previous methodprintMaxbecause those parameters are hidden. - The method
maximumexecutes its body and returns a value. Just before it returns, select the tabCall Treeabove the graphic display; the sequence of calls frommaintoprintMaxand thenmaximumis displayed. SelectTheaterto return to the animated display. - When the method returns, its activation record is deallocated, uncovering the activation record of
printMax. - The value returned is assigned to the variable
maxand printed. - When
printMaxcompletes its execution, its activation record is deallocated.
Note: In a call to a static method, the name of the class in which it is defined can be given as in the call to
maximum. Since the method is defined in the same class as the call, the class name need not be given, as shown in the call to printMax.Exercise Write a program to compute the maximum of six values using as few statements as possible.
Recursion
ConceptRecursion occurs when method calls itself. There is nothing at all mysterious about recursion! Each call simply creates a new activation record on the stack. However, to ensure that the recursive calls terminate, eventually, some call of the method should return without invoking itself once again.
Program: Method04.java
// Learning Object Method04
// recursion
public class Method04 {
static int factorial (int n) {
if (n <= 1)
return 1;
else
return n * factorial(n-1);
}
public static void main(/*String[] args*/) {
System.out.println(factorial(5));
}
}
The standard example of a recursive method is one that computes the factorial function:
n!=n·(n−1)·⋯·2·1=n·(n−1)!(1)
The recursion is terminated by defining n!=1 for n≤1.
- The
mainmethod calls the methodfactorialwith the actual parameter 5. This creates an activation record with the formal parameterninitialized to 5. - To compute the expression in the second return statement, the method
factorialis called again, this time with the actual parameter equal to 5−1=4. - The sequence of recursive calls continues five times, each one allocating a new activation record with a new variable
n. - Finally,
factorialis called with actual parameter 1. This call creates a new activation record as usual, but does not causefactorialto be invoked again. Instead, the value 1 is returned and the activation record is deallocated. Just before the method returns, select the tabCall Treeabove the graphic display; the sequence of calls frommainto the sequence of recursive calls is displayed. SelectTheaterto return to the animated display. - The recursive sequence unfolds: each returned value is used to compute a new value to be returned by that call of
factorial. - Finally, the value 120 is returned to the
mainmethod and printed.
Exercise Write a recursive method to compute the n'th Fibonacci number:
fib(0)=0,fib(1)=1,fib(n)=fib(n−1)+fib(n−2)forn>1.(2)
Exercise Write a more efficient nonrecursive method for the same function.
Calling methods on an object
Concept Nonstatic methods defined in a class must be invoked on an object of the class. A reference to the object becomes an implicit actual parameter that initializes a formal variable called
this in the method. The variable this need not be explicitly mentioned when accessing fields of the object unless there is an ambiguity.Program: Method05.java
// Learning Object Method05
// calling methods on an object
class Song {
int seconds;
Song(int s) {
seconds = s;
}
double computePrice(double pricePerSecond) {
return seconds * pricePerSecond;
}
}
public class Method05 {
public static void main(/*String[] args*/) {
Song song1 = new Song(164);
Song song2 = new Song(103);
double price1 = song1.computePrice(0.01);
double price2 = song2.computePrice(0.02);
System.out.println(price1);
System.out.println(price2);
}
}
This program computes the cost of a song as the product of its length in seconds and the price per second. A class
Song is defined to encapsulate the field seconds and the methodcomputePrice.- Two objects of class Song are instantiated and references to them are assigned to the variables
song1andsong2. - The method
computePriceis called on the object referenced bysong1. In Jeliot this is visualized by an arrow to the object placed in theExpression Evaluation Areafollowed by a period and the method name and parameters. - An activation record is allocated containing two formal parameters:
thisis initialized by the implicit reference andpricePerSecondis initialized from the actual parameter. - The reference in the parameter
thisis used to obtain the value of the fieldseconds. An expression is evaluated and its value returned. - The activation record is deallocated and the value returned is stored in the variable
price1. - A second call to the method is executed in exactly the same way, except that it is called on the object referenced by
song2. - The values of
price1andprice2are printed.
Exercise Modify the method so that the formal parameter is also named
seconds. Yes, it can be done! (Hint: read the Concept paragraph above.)Calling a method on the same object
Concept A nonstatic method defined in a class that is invoked on an object of the class can invoke another such method on the same object. The object for the second call is the same as the one on the first call, namely, the only referenced by
this. There is no need to explicitly write this and the object may be accessed implicitly.Program: Method06A.java
// Learning Object Method06A
// calling a method on the same object
class Song {
int seconds;
Song(int s) {
seconds = s;
}
boolean discount(int s) {
return s > 300;
}
double computePrice(double pricePerSecond) {
double price = seconds * pricePerSecond;
if (discount(seconds))
price = price * 0.9;
return price;
}
}
public class Method06A {
public static void main(/*String[] args*/) {
Song song1 = new Song(164);
Song song2 = new Song(403);
double price1 = song1.computePrice(0.01);
double price2 = song2.computePrice(0.01);
System.out.println(price1);
System.out.println(price2);
}
}
This program computes the cost of a song as the product of its length in seconds and the price per second. A discount is applied to “long” songs. A class
Song is defined to encapsulate the field seconds and the methods computePrice and discount.- Two objects of class Song are instantiated and references to them are assigned to the variables
song1andsong2. - The method
computePriceis called on the object referenced bysong1. In Jeliot this is visualized by an arrow to the object placed in theExpression Evaluation Areafollowed by a period and the method name and parameters. - An activation record is allocated containing two formal parameters:
thisis initialized by the implicit reference andpricePerSecondis initialized from the actual parameter. - The local variable
priceis declared and initialized by the expression calculated from the formal parameterpricePerSecondand the field of the objectsecondsthat is implicitly accessed throughthis. - The method
discount, declared in the same class, is invoked and returns a boolean value. A new activation is allocated for this method and deallocated when it terminates. The implicit actual parameter isthisand it is used to initialize the implicit formal parameterthisof the methoddiscount. - The activation record for
computePriceis deallocated and the value returned is stored in the variableprice1. - A second call to the method is executed exactly the same way, except that it is called on the object referenced by
song2. - The values of
price1andprice2are printed.
Exercise Modify the program so that discount does not use the explicit parameter
s.Program: Method06B.java
// Learning Object Method06B
// calling a method on the same object
class Song {
int seconds;
Song(int s) {
seconds = s;
}
static int level(int n) {
return n * 100;
}
boolean discount(int s) {
return s > level(3);
}
double computePrice(double pricePerSecond) {
double price = seconds * pricePerSecond;
if (discount(seconds))
price = price * 0.9;
return price;
}
}
public class Method06B {
public static void main(/* String[] args */) {
Song song1 = new Song(164);
Song song2 = new Song(403);
double price1 = song1.computePrice(0.01);
double price2 = song2.computePrice(0.01);
System.out.println(price1);
System.out.println(price2);
}
}
Given a call to a method
m2 within a method m1:void m1() {
m2();
}
it is impossible to tell from the call if m2 is being implicitly called on the same object or if it is a static method defined in the class.
- This program is a modification of the previous one: instead of comparing
swith 300 in the methoddiscount, it is compared with the value returned by the methodlevel. It is impossible to tell from the calls alone todiscountandlevelthat the first is a call on an object while the second is a call to a static method.
Exercise Modify the calls to
discount and level so that it is immediately apparent which is definitely a call on an object and which is definitely a call to a static method.Objects as parameters
Concept A reference to an object can be an actual parameter whose corresponding formal parameter is declared to be of the same class. As with all parameters, the value of actual parameter is used to initialize the formal parameter, but since it is a reference that is passed, the method that is called can access fields and methods of the object. This is calledreference semantics.
Program: Method07.java
// Learning Object Method07
// objects as parameters
class Song {
int seconds;
Song(int s) {
seconds = s;
}
double computePrice(double pricePerSecond) {
return seconds * pricePerSecond;
}
}
public class Method07 {
static double getPrice(Song s, double ppS) {
return s.computePrice(ppS);
}
public static void main(/*String[] args*/) {
Song song1 = new Song(164);
Song song2 = new Song(103);
double price1 = getPrice(song1, 0.01);
double price2 = getPrice(song2, 0.02);
System.out.println(price1);
System.out.println(price2);
}
}
This program computes the cost of a song as the product of its length in seconds and the price per second. A class
Song is defined to encapsulate the field seconds and the methodcomputePrice. The method getPrice in the main method receives an object of class Song as a parameter and calls computePrice.- Two objects of class Song are instantiated and references to them are assigned to the variables
song1andsong2. - The method
getPriceis called with two parameters: the first is a referencesong1to an object of classSong, while the second is a value of type double. The actual parameters are used to initialize the formal parameters; check thatsong1andsreference the same object. - Since the formal parameter
sreceives a reference to an object of classSong(in this casesong1), it can be used to call the methodcomputePricedeclared in the class. - The method returns a value that is assigned to
price1. - A second call to the method is executed exactly the same way, except that the actual parameter is the reference contained in
song2. - The values of
price1andprice2are printed.
Exercise Modify the program so that discount does not use the explicit parameter
s.Returning objects
Concept A return value can be a reference to an object.
Program: Method08.java
// Learning Object Method08
// returning objects
class Song {
int seconds;
Song(int s) {
seconds = s;
}
double computePrice(double pricePerSecond) {
return seconds * pricePerSecond;
}
}
public class Method08 {
static Song longer(Song s1, Song s2) {
if (s1.seconds > s2.seconds)
return s1;
else
return s2;
}
public static void main(/*String[] args*/) {
Song song1 = new Song(164);
Song song2 = new Song(103);
Song longerSong = longer(song1, song2);
double price2 = longerSong.computePrice(0.01);
System.out.println(price2);
}
}
This program computes the cost of a song as the product of its length in seconds and the price per second. A class
Song is defined to encapsulate the field seconds and the methodcomputePrice. The method longer in the main method receives references to two objects of class Song as parameters and returns a reference to the one with the larger value of the field seconds.- Two objects of class Song are instantiated and references to them are assigned to the variables
song1andsong2. - The method
longeris called with two parameters that are references to objects of classSong. The actual parameters are used to initialize the formal parameters; check thatsong1ands1reference the same object, as dosong2ands2. - Since the formal parameters
s1ands2receive references to objects of classSong, they can be used to access the fieldssecondsof each object. - The method returns the reference to the object whose field
secondshas the larger value. The reference is assigned to the variablelongerSong; check that this reference is to the same object as the reference insong1. - The reference in
longerSongis used to call the methodcomputePriceand the value returned is assigned to the variableprice2. - The value
price2is printed.
Exercise Modify the program so that discount does not use the explicit parameter
s.Exercise Replace the last declaration and statements of the program by one declaration.
Exercise Write a method to swap two integer values.
Returning locally instantiated objects
Concept When a method terminates, its activation record is deallocated. However, if an object has been instantiated within the method, a reference to the object can be returned to the calling method.
Program: Method09.java
// Learning Object Method09
// returning locally instantiated objects
class Song {
int seconds;
Song(int s) {
seconds = s;
}
double computePrice(double pricePerSecond) {
return seconds * pricePerSecond;
}
}
public class Method09 {
static Song doubleSong(Song s1) {
Song d = new Song(s1.seconds*2);
return d;
}
public static void main(/*String[] args*/) {
Song song1 = new Song(164);
Song longSong = doubleSong(song1);
}
}
This program computes the cost of a song as the product of its length in seconds and the price per second. A class
Song is defined to encapsulate the field seconds and the methodcomputePrice. The method double in the main method receives a reference to an object of class Song as a parameter and returns a reference to an new object of class Songwhose field seconds is twice as large.- Two objects of class Song are instantiated and references to them are assigned to the variables
song1andsong2. - The method
doubleSongis called with an actual parameter that is a referencesong1to an object of classSong. The actual parameter is used to initialize the formal parameter; check thatsong1ands1reference the same object. - Within the method, the
secondsfield of the object referenced bys1is used to instantiate a new object whose reference is assigned to the variabledof classSong. - The method returns the reference to the object contained in
d; althoughddisappears when the activation record is deallocated, the object still exists as does the reference that is returned. - The returned reference is assigned to the variable
longSong; check thatsong1andlongSongreference different objects!
No comments:
Post a Comment