95-712 object oriented programming java 1 some notes on cloning, packages and visibility notes from...
TRANSCRIPT
95-712 Object Oriented Programming Java
1
Some Notes on Cloning, Packages and Visibility
Notes from Bruce Eckel’s “Thinking in Java” and “Just Java” by Peter van der Linden
95-712 Object Oriented Programming Java
2
Review Passing Handles
• All arguments are passed as handles
• You never pass the object itself
• Very efficient if
– You’re only reading the object
– You want to modify the outside object
• Sometimes it’s necessary to create a “local”
– Changes only affect the local object, not the outside object
– Java doesn’t support this directly, but provides
“cloning”
95-712 Object Oriented Programming Java
3
Making Local Copies
In general, you call a method in order to produce a return value and/or a change of state in the object that the method is called for.
It is much less common to call a method in order to manipulate its arguments; this is referred to a “calling a method for its side effects”.
If you need to modify an argument during a method calland don’t intend to modify the outside argument, then youshould protect that argument by making a copy inside yourmethod.
95-712 Object Oriented Programming Java
4
Cloning Objects
• To produce pass- by- value effect, explicitly
clone the object that’s passed to your method.
class SomeClass {
void f( Sheep x) {
x = (Sheep) x. clone();
// Now we have a local sheep object
// Any changes to x are private changes
}
}
95-712 Object Oriented Programming Java
5
// A simple Int class
class Int {
private int i;
public Int( int i) { this.i = i; }
public void increment() { i++; }
public String toString() {
return Integer.toString( i);
}
}
95-712 Object Oriented Programming Java
6
public class Cloning {
public static void main( String args[]) {
Int v[] = new Int[10];
for( int i = 0; i < 10; i++ )
v[i] = new Int(i);
for(int i = 0; i < 10; i++)
System. out. print("v[" + i + "]=" + v[i]+ " ");
System.out.println();
Int v2[] = (Int[]) v. clone();
95-712 Object Oriented Programming Java
7
// Increment all v2's elements:
for(int i = 0; i < 10; i++)
v2[i].increment();
// See if it changed v's elements:
for(int i = 0; i < 10; i++)
System. out. print("v[" + i + "]=" + v[i]+ " ");
}
}
95-712 Object Oriented Programming Java
8
v[0]=0 v[1]=1 v[2]=2 v[3]=3 v[4]=4 v[5]=5 v[6]=6 v[7]=7 v[8]=8 v[9]=9
v[0]=1 v[1]=2 v[2]=3 v[3]=4 v[4]=5 v[5]=6 v[6]=7 v[7]=8 v[8]=9 v[9]=10
Only A Shallow Clone Is Available for Arrays.
• If you create a new class you must write code to make that class cloneable
• But why bother?
95-712 Object Oriented Programming Java
9
// Forgetting to clone may break encapsulation
class BankAccount {
private double balance;
public BankAccount() { balance = 0; }
public BankAccount(double initialBalance) { balance = initialBalance; }
public void deposit(double amount) { balance += amount; }
public void withdraw(double amount ) { balance = balance - amount; }
public double getBalance() { return balance; }
public String toString() { return Double.toString(balance); }
95-712 Object Oriented Programming Java
10
class Customer {
private BankAccount account;
private String name;
public Customer(String aName) {
name = aName;
account = new BankAccount(0);
}
public String getName() {
return name;
}
95-712 Object Oriented Programming Java
11
public BankAccount getAccount()
{
return account;
}
public void addToAccount(double amt) {
account.deposit(amt);
}
public String toString() {
return name + account;
}
95-712 Object Oriented Programming Java
12
// Anyone can withdraw money!
public class CustomerTest {
public static void main(String args[]) {
Customer joe = new Customer("Joeseph Smith");
BankAccount sureItsPrivate = joe.getAccount();
joe.addToAccount(1000);
sureItsPrivate.withdraw(100);
System.out.println(joe);
}
}
Joeseph Smith900.0
95-712 Object Oriented Programming Java
13
Adding Clonability to a class
• Object. clone( ) is protected so you can’t normally access it
• Must override and make it public
• Must also implement the Cloneable interface
– A flag:
interface Cloneable {} // Empty!
– Allows you to check it:
if( myHandle instanceof Cloneable) // …
– Tested by Object. clone( )
• Virtually always call Object.clone( ) in your
new clone (via super. clone( ) )
95-712 Object Oriented Programming Java
14
// Allow others to clone objects of class BankAccount
class BankAccount implements Cloneable {
private double balance;
public BankAccount() { balance = 0; }
public BankAccount(double initialBalance) { balance = initialBalance; }
public void deposit(double amount) { balance += amount; }
public void withdraw(double amount ) { balance = balance - amount; }
public double getBalance() { return balance; }
public String toString() { return Double.toString(balance); }
95-712 Object Oriented Programming Java
15
public Object clone() {
try {
Object clonedAccount = super.clone();
return clonedAccount;
}
catch(CloneNotSupportedException e) {
// can't happen -- we implement cloneable
return null;
}
}
}
95-712 Object Oriented Programming Java
16
class Customer {
private BankAccount account;
private String name;
public Customer(String aName) {
name = aName;
account = new BankAccount(0);
}
public String getName() {
return name;
}
95-712 Object Oriented Programming Java
17
public BankAccount getAccount() {
return (BankAccount)account.clone();
}
public void addToAccount(double amt) {
account.deposit(amt);
}
public String toString() {
return name + account;
}
}
95-712 Object Oriented Programming Java
18
// We can only review Joe's account.
// We can change it only through the proper interface.
public class CustomerTest {
public static void main(String args[]) {
Customer joe = new Customer("Joeseph Smith");
BankAccount sureItsPrivate = joe.getAccount();
joe.addToAccount(1000);
sureItsPrivate.withdraw(100);
System.out.println(joe);
}
}
Joeseph Smith1000.0
95-712 Object Oriented Programming Java
19
The Effect of Object. clone( )
• Copies the bits for the exact object (not just the root
class Object)
• Should always be the first part of your cloning process
(via super. clone( ) )
• Copies the handle values, but not what they’re
pointing to (a shallow copy)
95-712 Object Oriented Programming Java
20
• To perform a deep copy you must clone the contents
of the handles as well
• Once you make clone public, it remains public in derived
classes (the protected trick may only be used once).
95-712 Object Oriented Programming Java
21
Be Careful when cloning a class with references.
•We can provide a clone method for the Customer class.
•We have to remember to clone the account object.
95-712 Object Oriented Programming Java
22
class Customer implements Cloneable {
private BankAccount account;
private String name;
public Customer(String aName) {
name = aName;
account = new BankAccount(0);
}
public String getName() {
return name;
}
95-712 Object Oriented Programming Java
23
public BankAccount getAccount() {
return (BankAccount)account.clone();
}
public void addToAccount(double amt) {
account.deposit(amt);
}
public String toString() {
return name + "\t" + account;
}
95-712 Object Oriented Programming Java
24
public Object clone() {
try {
Object clonedCustomer = super.clone();
((Customer)clonedCustomer).account =
(BankAccount)account.clone();
return clonedCustomer;
}
95-712 Object Oriented Programming Java
25
catch(CloneNotSupportedException e)
{
// can't happen we implement
// cloneable
return null;
}
}
}
95-712 Object Oriented Programming Java
26
public class CustomerTest2 {
public static void main(String args[]) {
Customer list[] = new Customer[3];
Customer list2[];
list[0] = new Customer("Mike");
list[1] = new Customer("Sue");
list[2] = new Customer("Bill");
list2 = (Customer[]) list.clone();
95-712 Object Oriented Programming Java
27
for(int j = 0; j < 3; j++) {
list2[j] = (Customer) list[j].clone();
list2[j].addToAccount(100);
}
for (int j = 0; j < 3; j++)
System.out.print(list[j] + "\t");
System.out.println();
for (int j = 0; j < 3; j++)
System.out.print(list2[j] + "\t");
}
}
95-712 Object Oriented Programming Java
28
Inserting Clonability in a derived class
class Person {}
class Hero extends Person {}
class Scientist extends Person implements Cloneable {
public Object clone() {
try {
return super. clone();
} catch (CloneNotSupportedException e) {
95-712 Object Oriented Programming Java
29
// This should never happen:
// It's Cloneable already!
throw new InternalError();
}
}
}
class MadScientist extends Scientist {}
95-712 Object Oriented Programming Java
30
public class HorrorFlick {
public static void main( String args[]) {
Person p = new Person();
Hero h = new Hero();
Scientist s = new Scientist();
MadScientist m = new MadScientist();
// p = (Person) p. clone(); // Compile error
// h = (Hero) h. clone(); // Compile error
s = (Scientist) s. clone();
m = (MadScientist) m. clone();
}
95-712 Object Oriented Programming Java
31
// Snake.java
public class Snake implements Cloneable {
private Snake next;
private char c;
// Value of i == number of segments
Snake(int i, char x) {
c = x;
if(--i > 0)
next = new Snake(i, (char)(x +1));
}
95-712 Object Oriented Programming Java
32
void increment() {
c++;
if(next != null)
next.increment();
}
public String toString() {
String s = ":" + c;
if(next != null)
s += next.toString();
return s;
}
95-712 Object Oriented Programming Java
33
public Object clone() {
Object o = null;
try {
o = super.clone();
} catch (CloneNotSupportedException e) {}
return o;
}
95-712 Object Oriented Programming Java
34
public static void main(String[] args) {
Snake s = new Snake(5, 'a');
System.out.println("s = " + s);
Snake s2 = (Snake)s.clone();
System.out.println("s2 = " + s2);
s.increment();
System.out.println(
"after s.increment, s2 = " + s2);
}
}
95-712 Object Oriented Programming Java
35
C:\McCarthy\eckelbook\source\c12>java Snake
s = :a:b:c:d:e
s2 = :a:b:c:d:e
after s.increment, s2 = :a:c:d:e:f
95-712 Object Oriented Programming Java
36
Homework
Why doesn’t snake.java work properly?
What changes would you make to fix it?
95-712 Object Oriented Programming Java
37
Packages and Visibility
95-712 Object Oriented Programming Java
38
package A;
public class Foo { int x; void bar() { Example e = new Example(); x = e.i; x = e.j; x = e.k; x = e.l; }}
package A;
public class Example { public int i;
int j; //package
protected int k;
private int l;
}
Access Between Two Classes in the Same Package
95-712 Object Oriented Programming Java
39
package B;import A.*;public class Foo { int x; void bar() { Example e = new Example(); x = e.i; x = e.j; x = e.k; x = e.l; }}
package A;
public class Example { public int i;
int j; //package
protected int k;
private int l;
}
Access Between Two Unrelated Classes in Different Packages
95-712 Object Oriented Programming Java
40
package B;import A.Example;public class Fooextends A.Example { int x; void bar() { Example e = new Example(); x = e.i; x = e.j; x = e.k; x = e.l; x = this.k; //OK! }}
package A;
public class Example { public int i;
int j; //package
protected int k;
private int l;
}
Access Between A Parent and Child Class in Different Packages