Documente Academic
Documente Profesional
Documente Cultură
By
Javed Siddique
Objectives
This week we will study:
methods returning objects
the reserved word this
overloading
class methods and variables
pass-by-value parameter passing
javadoc comments
packages
Returning an Object from a Method
return simp;
}
f1
simp
f2
: Fraction : Fraction
numerator numerator
24 2
denominator denominator
36 3
A Sample Call to simplify
public Fraction simplify( ) {
return simp;
}
f1
simp
f2
: Fraction : Fraction
numerator numerator
24 2 The value of simp, which is
a reference, is returned and
denominator denominator assigned to f2.
36 3
Reserved Word this
The reserved word this is called a self-
referencing pointer because it refers to an object
from the object's method.
: Object
this
int a, b, c, d;
Fraction sum;
return sum;
}
f3 = f1.add(f2)
f1 this Callee’s memory
f2 frac
f3
f2 frac
f3
int age;
int age;
class Person {
int age;
use the }
Person getFather(){
class Corruptor {
return father;
Jedi luke;
}
Person p;
}
public static void main(String[] args){
luke = new Jedi(new Person(“ObiWan”)); class Jedi {
p = luke.getFather(); private Person father;
p.setName(“Darth Vader”);
p = luke.getFather(); public void Jedi(Person f){
System.out.println(p.getName()); father = f;
} }
}
Person getFather(){
Person x;
x = new Person(father);
return x;
}
}
Summary of this
The reserved word this can be used to
1. Access methods of the same class from
another method of the class.
this. getNumerator(); numerator = 5;
2. Access data members of the class from a
method of the class
this. numerator = 5;
3. Call the constructor of the class
this(0,1);
Class (static) Methods
Some methods do not access object data
members. No need to call them on objects.
These can be declared as class methods.
They are called by using the class name.
E.g. the Math class methods.
We use the reserved word static to define a class
method.
public static int gcd(int m, int n) {
//the code implementing the Euclidean algorithm
}
class Test {
Account acc1, acc2;
acc1 = new Account();
acc2 = new Account();
System.out.println(“Acc1: “ + acc1.getAccountNumber());
System.out.println(“Acc2: “ + acc2.getAccountNumber());
}
Memory Diagram
Account
Account
-PREFIX
PREFIX
-nextAccount US_
nextAccount
+Account( ): void 100
101
102
+getAccountNumber( ):String
acc1 acc2
static {
String str;
str = JOptionPane.showInputDialog(null, "enter
starting value");
nextValue = Integer.parseInt(str);
}
public static void main(String[] args)
{
}
As with static methods, we cannot reference
any non-static method or data member from
the static initializer block.
The null constant
null is a special value. Its type is that of a
reference to an object (of any class).
We can set an object identifier to this value
to show that it does not point to any object.
Bicycle bike1=null;
A method that returns objects (of any
class) can return a null value.
Note that you will get a run-time error if you
access a data member of call a method of
a null object -- null pointer exception.
Testing for null values.
class Account {
private Person owner;
public Account(){
owner=null; We can use == or != to
}
public void setOwner(Person p){
check if an object
owner = p; reference
}
public Person getOwner(){ is null or not.
return(owner);
}
}
class Bank {
public static void main(String[] arg){
Account acc = new Account();
Person p;
…
p = acc.getOwner();
if (p==null)
System.out.println(“No owner”);
…
}
Wrapper Classes
There is a wrapper class for each primitive
data type.
Wrapper classes create an object out of a
primitive data type. What is the use?
We can provide extra functionality
Parsing, converting to and from strings
Type casting (doubleValue), toHexString
Constants such as PI, E, MAX_VALUE
See java API for details
Sometimes we must have an object.
Boxing and Unboxing
Converting a primitive to its corresponding
wrapper is called boxing
Converting a wrapper to its corresponding
primitive type is called unboxing.
In earlier versions of Java converting was a little
painful:
Integer iObj = new Integer(5);
int j = iObj.intValue();
Java 5 does this automatically:
Integer iObj = 5;
int j = iObj;
Autoboxing, Auto-unboxing
Automatic boxing and unboxing is
convenient.
This also works when converting actual to
formal parameters.
E.g. if a method expects an Integer object,
you can (in Java 5) simply pass an int
value or int literal
addToCollection(Integer iObj){ … }
addToCollection(5);
addToCollection(i);
Overloading and Type casting
Automatic (un)boxing and type casting is used
with overloaded methods.
BUT, only if no matching method is found before
automatic type conversion.
int i;
doMyThing(i);
This call can match:
1. doMyThing(int) OR
2. doMyThing(long) doMyThing(Integer)
doMyThing(double) …
BE CAREFUL!
Call-by-Value Parameter Passing
When a method is called,
the value of the argument is passed to the matching
parameter, and
separate memory space is allocated to store this
value.
This way of passing the value of arguments is
called a pass-by-value or call-by-value scheme.
Since separate memory space is allocated for
each parameter during the execution of the
method,
the parameter is local to the method, and therefore
changes made to the parameter will not affect the
value of the corresponding argument.
Call-by-Value Example
class Tester {
public void myMethod(int one, double two ) {
one = 25;
two = 35.4;
}
}
Tester tester;
int x, y;
tester = new Tester(); 10 20
x = 10; produces
y = 20;
tester.myMethod(x, y);
System.out.println(x + " " + y);
Memory Allocation for Parameters
Tester tester; class Tester {
int x, y; public void myMethod(int one, double two ){
tester = new Tester(); 2 one = 25;
x = 10; two = 35.4;
}
y = 20;
1
tester.myMethod(x, y); }
System.out.println(x + " " + y);
x
1 10
one 2
10
y two
20 20.0
Memory Allocation for Parameters
Tester tester; class Tester {
int x, y; public void myMethod(int one, double two ){
tester = new Tester(); one = 25;
x = 10; two = 35.4;
y = 20; 3 }
tester.myMethod(x, y); 4 }
System.out.println(x + " " + y);
x
10
one 3
10
25
y two
20
20.0
35.4
Parameter Passing: Key Points
1. Arguments are passed to a method by using the pass-by- value scheme.
2. Arguments are matched to the parameters from left to right. The data
type of an argument must be assignment-compatible with the data type of
the matching parameter.
3. The number of arguments in the method call must match the number of
parameters in the method definition.
4. Parameters and arguments do not have to have the same name.
5. Local copies, which are distinct from arguments,are created even if the
parameters and arguments share the same name.
6. Parameters are input to a method, and they are local to the method.
Changes made to the parameters will not affect the value of
corresponding arguments.
7. When we pass objects, the reference to the object is passed, therefore,
objects get modified.
Organizing Classes into a Package
For a class A to use class B, their bytecode
files must be located in the same directory.
This is not practical if we want to reuse
programmer-defined classes in many different
programs
The correct way to reuse programmer-
defined classes from many different
programs is to place reusable classes in a
package.
A package is a Java class library.
Creating a Package
The following steps illustrate the process of
creating a package named myutil that includes
the Fraction class.
1. Include the statement
package myutil;
as the first statement of the source file for the Fraction class.
2. The class declaration must include the visibility modifier public as
public class Fraction {
...
}
3. Create a folder named myutil, the same name as the package name.
In Java, the package must have a one-to-one correspondence with the
folder.
4. Place the modified Fraction class into the myutil folder and compile it.
5. Modify the CLASSPATH environment variable to include the folder that
contains the myutil folder.
Multiple classes per file
So far, we only defined a single class per
file.
It is possible to define multiple classes in a
single file.
However, only one file can be public. This
class must have the same name as the file
(.java).
Only public classes can be imported.
Program Structure and Source Files
class Test1 {
…
}
class Test2 {
…
}
Test2.class
Program Structure and Source Files
class Test1 {
public static void main (String[] arg) {
…
}
}
class Test2 {
public static void main (String[] arg) {
…
}
}
Can execute:
Test1.class
javac Test.java %java Test1
%java Test2
Test.java
Test2.class
Program Structure and Source Files
package myPack;
public class Test1 { import myPack;
public static void main (String[] arg) { class Tester {
… public static void main (String[] arg) {
} Test1 t;
} …
class Test2 { }
}
}
Tester.java
javac Test.java Test1.class
Test.java
CLASSPATH must
include myPack
myPack Test2.class
X is: 3 X is: 11
int x=2, y=10, z; int x=2, y=10;
Y is: 9 Y is: 11
z = x++ * --y; Z is: 18 x = --x * ++y;
System.out.println(“X is:” + x); System.out.println(“X is:” + x);
System.out.println(“Y is:” + y); System.out.println(“Y is:” + y);
System.out.println(“Z is:” + z);
Side effects -- 1
int
x= 1, y=10, z=100;
boolean bool, test=false;
x = y++; x: 10 y: 11
x = ++y; x: 11 y: 11
x = -y++; x: -11 y: 10
x = -++y; x: -11 y: 11
x = -y++; x: -10 y: 11
x = -y--; x: -10 y: 9
x = -(--y); x: -9 y: 9
x = ++y++; ERROR!
Prefix vs. postfix.
A prefix (postfix) operator is equivalent to
executing the operator before (after) using
the value of the variable:
z = x++ * --y;
Is equivalent to:
y = y-1;
z = x * y;
x = x + 1;
What about:
z = x++ * x++;
More Examples
z = x++ * x++;
Is equivalent to:
z = x * (x+1);
x = x+2;
x = x++ * --y;
Is equivalent to:
y = y - 1;
x = x * (y-1);
Side effects -- 2
int
x= 1, y=10, z=100;
boolean bool, test=false;
x = y = z; x: 100 y: 100 z: 100
x = y = ++z; x: 101 y: 101 z: 101
bool = (x=11)>y x: 11 y: 10 bool: true
bool = (x=11)>y++ x: 11 y: 11 bool: true
bool = (x=11)> ++y x: 11 y: 11 bool: false
x: 3 y: 11 z: 100
(x=3) > y && (z=5)<10
(x=3) > y & (z=5)<10 x: 3 y: 11 z: 5
What is the output?
What are the values of x and y after this
code is exectued?
int x=2, y=10;
x = x++*--y;
System.out.println(“X is:” + x);
System.out.println(“Y is:” + y);
55
Problem Statement
Write a SlotMachine game.
User will enter initial balance. The SlotMachine
has three dice. If all three numbers of the slot
machine are different then the balance will be
reduced. If two numbers are same then the
balance remains the same. If all three dice have
different numbers then the balance is reduced.
The user can cache out any time. Otherwise
he/she can play as long as his/her balance is
greater than zero.
Overall Plan
Tasks:
• Get Users initial balance.
• Play the game if initial balance is greater than
zero.
• Change balance according to the results of
three dice.
• Ask the user if he/she wants to play again.
• Repeat this step until the user quits.
Required Classes
Main
helper class
Development Steps
We will develop this program in five
steps:
1. Define the basic Dice class.
2. Define the Slot Machine class.
3. Define the top-level Main class.
Step 1 Design
Develop the Dice class.
The key design task is to identify the
data members for storing relevant
information.
We will include multiple constructors for
ease of creating objects.
Make sure that an instance will be initiated
correctly no matter which constructor is
used.
Passing a name to dice.
Step 1 Test
Build a Main class and use the Dice class.
Make sure the Dice Class works perfectly.
Otherwise your SlotMachine will not work
properly.
Step 2 Design
Use the Dice Class to make the
SlotMachine class.
A SlotMachine has three Dice.
This is the containment
relationship.
A SlotMachine also has an initial
balance and score.
Step 2 Test
In the testing phase, we make a main
program and Test the SlotMachine
class multiple times.
We make sure that the SlotMachine
meets our expectation before moving
to the next step.
Step 3 Design
We implement the top-level control class
Main.
The top-level controller interacts with the
user and uses the SlotMachine class.
The top-level controller manages the input
and output routines
If the input and output routines are complex,
then we would consider designing separate
classes to delegate the I/O tasks.
Step 3 Test
Now we run the program multiple times,
trying different input types and values.
We make sure that all the rules and
conditions are covered by our test cases.
In this case what should be our test cases?
Testing is a mandatory industry practice.
Almost equal amount time is spent on
software testing and software design and
development (coding).