Transcript ppt

Last Time
• Started Encapsulation (using some rather strange
analogies!)
Winter 2006
CISC121 - Prof. McLeod
1
Stuff
• Note that PrimeNums sample files on web site
have been updated (last night). Please download
them again if you have already done so.
• Only the files
– TestPrimeNumsPrivacy.java
– PrimeNumsException.java
have not changed.
Winter 2006
CISC121 - Prof. McLeod
2
Today
• Continue Encapsulation
Winter 2006
CISC121 - Prof. McLeod
3
So Far,
• “We” decided that attributes must be declared
private. Otherwise the object cannot control
the value of the attribute.
• To set the value of the attribute you can use the
constructor upon instantiation, or invoke a mutator
method.
• Either method could throw an exception if an
attempt is made to set the attribute(s) to illegal
values.
Winter 2006
CISC121 - Prof. McLeod
4
PrimeNums Mutator?
• You can decide whether to add a “set” method to
your class or not.
• If you do, this means the user can create an
empty instance of PrimeNums and then populate
it, or you can change the contents of a
PrimeNums object any time.
• How does the mutator indicate a problem?
• See PrimeNumsWithMutator.java and
TestPrimeNumsWithMutator.java.
Winter 2006
CISC121 - Prof. McLeod
5
More Questions!
• Why does the constructor and the mutator assign
the array nums element by element instead of
using nums = array;?
• Why does PrimeNumsWithMutator need an
empty (or “default”) constructor?
• Remember the first version of PrimeNums? (Slide
6 – Feb. 7 lecture) It did not have any
constructors, but we could still instantiate it. What
is going on here?
Winter 2006
CISC121 - Prof. McLeod
6
Default Constructors
• If you do not have any constructors, the compiler
will create an empty, or “default”, constructor for
you. It has no parameters and does nothing.
• If you write any constructor yourself, then the
compiler no longer supplies the default
constructor.
– In this case if you want an empty constructor (no
parameters), you will need to write it yourself.
Winter 2006
CISC121 - Prof. McLeod
7
Accessor Methods
• We need to have some way to get the data back
out of the Object. Right? Why?
• This is done using accessor or “get” methods.
• What is the problem with:
public int[] getNums () {
return nums;
}
Winter 2006
CISC121 - Prof. McLeod
8
A Better Accessor for PrimeNums
public int[] getNums () {
int[] temp = new int[nums.length];
for (int i = 0; i < temp.length; i++)
temp[i] = nums[i];
// or use:
// int[] temp = nums.clone();
return temp;
} // end getNums accessor
Winter 2006
CISC121 - Prof. McLeod
9
Aside - the clone() Method
• It is the only method that an array has.
• It returns a full, but completely independent copy
of the array.
• It is not aliased to the original array at all.
• (It is called a “deep copy” by some coders.)
• Note clone() does not work on 2D arrays – it
produces only a “shallow copy”.
• Nearly all objects in Java have a clone()
method, so (as not to be different!) we should put
one in our PrimeNums class.
Winter 2006
CISC121 - Prof. McLeod
10
What Else does PrimeNums Need?
• There are many standard methods that can be
added to a class, depending on its purpose.
These three are fairly standard to all classes:
– toString()
– equals()
– compareTo()
Winter 2006
CISC121 - Prof. McLeod
11
toString() Method
• As it is, if we try to print a PrimeNums object, we
will just get “gobbldeygook”:
PrimeNums@923e30
• (This String is composed of the object type and its
hash code…)
• So, to get a more useful view of the contents of
the object, define a toString() method that
returns a String.
Winter 2006
CISC121 - Prof. McLeod
12
toString() Method, Cont.
public String toString () {
String s = "Array contents: ";
for (int i = 0; i < nums.length; i++)
s = s + nums[i] + " ";
return s;
} // end toString method
Winter 2006
CISC121 - Prof. McLeod
13
equals() Method
• Accepts another object of type PrimeNums and
returns true of they are equal, false otherwise.
• You get to define what “equality” means.
Winter 2006
CISC121 - Prof. McLeod
14
equals() Method, Cont.
public boolean equals (CompletePrimeNums
otherPrimeNums) {
if (nums.length != otherPrimeNums.nums.length)
return false;
//It would make more sense to sort both arrays first!
for (int i = 0; i < nums.length; i++)
if (nums[i] != otherPrimeNums.nums[i])
return false;
return true;
} // end equals
Winter 2006
CISC121 - Prof. McLeod
15
Aside - the equals() Method in Object
• Every object created in Java inherits all the
methods in the Object class, including:
public boolean equals (Object o) {….}
• This method only compares memory addresses.
• Not much use!
• Advanced topic: How to override this method.
Winter 2006
CISC121 - Prof. McLeod
16
Aside - the equals() Method in Object,
Cont.
• The proper equals method would start out like:
public boolean equals (Object o) {
if (o == null) return false;
if (!(o instanceof CompletePrimeNums)) return false;
CompletePrimeNums otherPrimeNums =(CompletePrimeNums)o;
// rest of method is the same
Winter 2006
CISC121 - Prof. McLeod
17
Aside - the equals() Method in Object,
Cont.
• A couple of new things here:
– instanceof – checks to see if an object’s
underlying type matches a certain type.
– Casting a generic Object to be a specific type.
(You should never do this unless you have
checked the type by using instanceof first!)
Winter 2006
CISC121 - Prof. McLeod
18
compareTo() Method
• Compares a supplied PrimeNums object with the
current one, based on your comparison criteria.
• It returns an int value.
• (Like the compareTo() method in the String
class.)
Winter 2006
CISC121 - Prof. McLeod
19
compareTo() Method, Cont.
public int compareTo (CompletePrimeNums otherPrimeNums)
{
// Assume a comparison based on length of array
//only
return nums.length - otherPrimeNums.nums.length;
} // end compareTo
Winter 2006
CISC121 - Prof. McLeod
20
compareTo() Method, Cont.
• Object does not have a compareTo() method,
so we don’t have to override one.
• You could still write compareTo() as:
public int compareTo (Object o) {…}
• If instanceof returns false what do you do?
Winter 2006
CISC121 - Prof. McLeod
21
clone() Method
public CompletePrimeNums clone () {
CompletePrimeNums temp = null;
try {
temp = new CompletePrimeNums(getNums());
} catch (PrimeNumsException e) {
// do nothing!
} // end try catch
return temp;
} // end clone method
Winter 2006
CISC121 - Prof. McLeod
22
clone() Method, Cont.
• By calling getNums() we are not worried about
aliasing, since getNums() already takes care of
that.
• Do we ever have to worry about actually catching
a PrimeNumsException here?
• (The instantiation still has to be in a try/catch
block – as dictated by the merciless compiler!)
• This clone() method makes a proper, “deep”
copy of the current object.
Winter 2006
CISC121 - Prof. McLeod
23
A Complete PrimeNums Class
• Look at “CompletePrimeNums.java”
• Methods in CompletePrimeNums:
–
–
–
–
–
–
–
–
CompletePrimeNums ()
CompletePrimeNums (int[]) throw
PrimeNumsException
void setNums (int[])
int[] getNums ()
String toString ()
boolean equals (Object)
int compareTo (CompletePrimeNums)
CompletePrimeNums clone ()
Winter 2006
CISC121 - Prof. McLeod
24
Demonstrating Privacy Violations
• (in a clean way!)
• Look at “CompletePrimeNumsNoPrivacy.java”
and “TestPrimeNumsPrivacy.java” to see the
effects of privacy leaks!
• (Also contains a more sophisticated toString()
method.)
Winter 2006
CISC121 - Prof. McLeod
25