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
x
andy
are allocated and initialized. - The method is called with the values of the actual parameters
x
andy
. - 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
max
is 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
x
andy
are allocated and initialized; the variablemax
is 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
x
andy
. - 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 b
is executed, the value ofb
is 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
max
is 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
main
method calls the methodprintMax
; the actual parameters are two integer literals. - The activation record for
printMax
is allocated, and the actual parameters are used to initialize the formal parametersa
andb
. - The variable
max
is allocated but not initialized. - The method
maximum
is called; the actual parameters are the values ofa
andb
, 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 parametersa
andb
; note that these are new parameters not at all related to the formal parameters of the same names in the previous methodprintMax
because those parameters are hidden. - The method
maximum
executes its body and returns a value. Just before it returns, select the tabCall Tree
above the graphic display; the sequence of calls frommain
toprintMax
and thenmaximum
is displayed. SelectTheater
to 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
max
and printed. - When
printMax
completes 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
main
method calls the methodfactorial
with the actual parameter 5. This creates an activation record with the formal parametern
initialized to 5. - To compute the expression in the second return statement, the method
factorial
is 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,
factorial
is called with actual parameter 1. This call creates a new activation record as usual, but does not causefactorial
to be invoked again. Instead, the value 1 is returned and the activation record is deallocated. Just before the method returns, select the tabCall Tree
above the graphic display; the sequence of calls frommain
to the sequence of recursive calls is displayed. SelectTheater
to 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
main
method 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
song1
andsong2
. - The method
computePrice
is called on the object referenced bysong1
. In Jeliot this is visualized by an arrow to the object placed in theExpression Evaluation Area
followed by a period and the method name and parameters. - An activation record is allocated containing two formal parameters:
this
is initialized by the implicit reference andpricePerSecond
is initialized from the actual parameter. - The reference in the parameter
this
is 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
price1
andprice2
are 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
song1
andsong2
. - The method
computePrice
is called on the object referenced bysong1
. In Jeliot this is visualized by an arrow to the object placed in theExpression Evaluation Area
followed by a period and the method name and parameters. - An activation record is allocated containing two formal parameters:
this
is initialized by the implicit reference andpricePerSecond
is initialized from the actual parameter. - The local variable
price
is declared and initialized by the expression calculated from the formal parameterpricePerSecond
and the field of the objectseconds
that 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 isthis
and it is used to initialize the implicit formal parameterthis
of the methoddiscount
. - The activation record for
computePrice
is 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
price1
andprice2
are 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
s
with 300 in the methoddiscount
, it is compared with the value returned by the methodlevel
. It is impossible to tell from the calls alone todiscount
andlevel
that 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
song1
andsong2
. - The method
getPrice
is called with two parameters: the first is a referencesong1
to an object of classSong
, while the second is a value of type double. The actual parameters are used to initialize the formal parameters; check thatsong1
ands
reference the same object. - Since the formal parameter
s
receives a reference to an object of classSong
(in this casesong1
), it can be used to call the methodcomputePrice
declared 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
price1
andprice2
are 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
song1
andsong2
. - The method
longer
is called with two parameters that are references to objects of classSong
. The actual parameters are used to initialize the formal parameters; check thatsong1
ands1
reference the same object, as dosong2
ands2
. - Since the formal parameters
s1
ands2
receive references to objects of classSong
, they can be used to access the fieldsseconds
of each object. - The method returns the reference to the object whose field
seconds
has 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
longerSong
is used to call the methodcomputePrice
and the value returned is assigned to the variableprice2
. - The value
price2
is 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 Song
whose field seconds
is twice as large.- Two objects of class Song are instantiated and references to them are assigned to the variables
song1
andsong2
. - The method
doubleSong
is called with an actual parameter that is a referencesong1
to an object of classSong
. The actual parameter is used to initialize the formal parameter; check thatsong1
ands1
reference the same object. - Within the method, the
seconds
field of the object referenced bys1
is used to instantiate a new object whose reference is assigned to the variabled
of classSong
. - The method returns the reference to the object contained in
d
; althoughd
disappears 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 thatsong1
andlongSong
reference different objects!
No comments:
Post a Comment