250 likes | 358 Views
Last Time. Started Encapsulation (using some rather strange analogies!). 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
E N D
Last Time • Started Encapsulation (using some rather strange analogies!) CISC121 - Prof. McLeod
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. CISC121 - Prof. McLeod
Today • Continue Encapsulation CISC121 - Prof. McLeod
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. CISC121 - Prof. McLeod
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. CISC121 - Prof. McLeod
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? CISC121 - Prof. McLeod
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. CISC121 - Prof. McLeod
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; } CISC121 - Prof. McLeod
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 CISC121 - Prof. McLeod
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.) • Noteclone() 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. CISC121 - Prof. McLeod
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() CISC121 - Prof. McLeod
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. CISC121 - Prof. McLeod
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 CISC121 - Prof. McLeod
equals() Method • Accepts another object of type PrimeNums and returns true of they are equal, false otherwise. • You get to define what “equality” means. CISC121 - Prof. McLeod
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 CISC121 - Prof. McLeod
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. CISC121 - Prof. McLeod
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 CISC121 - Prof. McLeod
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!) CISC121 - Prof. McLeod
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.) CISC121 - Prof. McLeod
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 CISC121 - Prof. McLeod
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? CISC121 - Prof. McLeod
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 CISC121 - Prof. McLeod
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. CISC121 - Prof. McLeod
A Complete PrimeNums Class • Look at “CompletePrimeNums.java” • Methods in CompletePrimeNums: • CompletePrimeNums () • CompletePrimeNums (int[]) • void setNums (int[]) • int[] getNums () • String toString () • boolean equals (Object) • int compareTo (CompletePrimeNums) • CompletePrimeNums clone () throw PrimeNumsException CISC121 - Prof. McLeod
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.) CISC121 - Prof. McLeod