[ Pobierz całość w formacie PDF ]
.clone( ), which throws an exception and prevents cloning.[ Add Comment ]But what if the programmer doesn’tfollow the “proper” path of callingsuper.clone( )inside the overridden clone( ) method? In BackOn, you can seehow this can happen.This class uses a separate method duplicate( )to make a copy of the current object and calls this method insideclone( ) instead of calling super.clone( ).Theexception is never thrown and the new class is cloneable.You can’t relyon throwing an exception to prevent making a cloneable class.The only sure-firesolution is shown in ReallyNoMore, which is final and thus cannotbe inherited.That means if clone( ) throws an exception in thefinal class, it cannot be modified with inheritance and the prevention ofcloning is assured.(You cannot explicitly call Object.clone( ) froma class that has an arbitrary level of inheritance; you are limited to callingsuper.clone( ), which has access to only the direct base class.)Thus, if you make any objects that involve security issues, you’ll want tomake those classes final.[ Add Comment ]The first method you see in classCheckCloneable is tryToClone( ), which takes anyOrdinary object and checks to see whether it’s cloneable withinstanceof.If so, it casts the object to an IsCloneable, callsclone( ) and casts the result back to Ordinary, catching anyexceptions that are thrown.Notice the use of run-time type identification (seeChapter 12) to print the class name so you can see what’s happening.[ Add Comment ]In main( ), different typesof Ordinary objects are created and upcast to Ordinary in thearray definition.The first two lines of code after that create a plainOrdinary object and try to clone it.However, this code will not compilebecause clone( ) is a protected method in Object.Theremainder of the code steps through the array and tries to clone each object,reporting the success or failure of each.The output is:[ Add Comment ]Attempting IsCloneableCloned IsCloneableAttempting NoMoreCould not clone NoMoreAttempting TryMoreCould not clone TryMoreAttempting BackOnCloned BackOnAttempting ReallyNoMoreCould not clone ReallyNoMoreSo to summarize, if you want a class tobe cloneable:[ Add Comment ]Implement theCloneableinterface.Overrideclone( ).Callsuper.clone( ) inside yourclone( ).Captureexceptions inside yourclone( ).Thiswill produce the most convenient effects.[ Add Comment ]The copy constructorCloning can seem to be a complicatedprocess to set up.It might seem like there should be an alternative.Oneapproach that might occur to you (especially if you’re a C++ programmer)is to make a special constructor whose job it is to duplicate an object.In C++,this is called the copyconstructor.At first, this seems like the obvious solution, but in fact itdoesn’t work.Here’s an example://: appendixa:CopyConstructor.java// A constructor for copying an object of the same// type, as an attempt to create a local copy.class FruitQualities {private int weight;private int color;private int firmness;private int ripeness;private int smell;// etc.FruitQualities() { // Default constructor// do something meaningful.}// Other constructors://.// Copy constructor:FruitQualities(FruitQualities f) {weight = f.weight;color = f.color;firmness = f.firmness;ripeness = f.ripeness;smell = f.smell;// etc.}}class Seed {// Members.Seed() { /* Default constructor */ }Seed(Seed s) { /* Copy constructor */ }}class Fruit {private FruitQualities fq;private int seeds;private Seed[] s;Fruit(FruitQualities q, int seedCount) {fq = q;seeds = seedCount;s = new Seed[seeds];for(int i = 0; i < seeds; i++)s[i] = new Seed();}// Other constructors://.// Copy constructor:Fruit(Fruit f) {fq = new FruitQualities(f.fq);seeds = f.seeds;// Call all Seed copy-constructors:for(int i = 0; i < seeds; i++)s[i] = new Seed(f.s[i]);// Other copy-construction activities
[ Pobierz całość w formacie PDF ]