33
CS 1302 – Lab 4 This is a tutorial on abstract classes and interfaces. There are 4 stages to complete this lab: Stag e Title Text Reference 1 Abstract Classes 13.1-13.2 2 Interfaces 13.5 3 The Comparable Interface 13.6 4 The Cloneable Interface 13.7 To make this document easier to read, it is recommend that you turn off spell checking in Word: 1. Choose: File, Option, Proofing 2. At the very bottom, check: “Hide spelling errors…” and “Hide grammar errors…” Stage 1 - Abstract Classes In this stage we introduce the concept of an abstract class. 1. (Read, no action required). a. An abstract class is one that defines methods and instance variables just like a regular class; however, it also defines some abstract methods. Abstract methods specify only the signature of a method, but no implementation. Thus, an abstract class is incomplete. You cannot create an instance of an abstract class but you can extend one. When you extend an abstract class you must implement the abstract methods. b. Study the figure below and note the following: We use the abstract modifier to define an abstract class. We use the abstract modifier to define the signature of an abstract method. The Dog subclass must implement the abstract method, makeSound. 1

mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

Embed Size (px)

Citation preview

Page 1: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

CS 1302 – Lab 4

This is a tutorial on abstract classes and interfaces. There are 4 stages to complete this lab:

Stage Title Text Reference1 Abstract Classes 13.1-13.22 Interfaces 13.53 The Comparable Interface 13.64 The Cloneable Interface 13.7

To make this document easier to read, it is recommend that you turn off spell checking in Word:

1. Choose: File, Option, Proofing2. At the very bottom, check: “Hide spelling errors…” and “Hide grammar errors…”

Stage 1 - Abstract Classes

In this stage we introduce the concept of an abstract class.

1. (Read, no action required).

a. An abstract class is one that defines methods and instance variables just like a regular class; however, it also defines some abstract methods. Abstract methods specify only the signature of a method, but no implementation. Thus, an abstract class is incomplete. You cannot create an instance of an abstract class but you can extend one. When you extend an abstract class you must implement the abstract methods.

b. Study the figure below and note the following:

We use the abstract modifier to define an abstract class. We use the abstract modifier to define the signature of an abstract method. The Dog subclass must implement the abstract method, makeSound.

1

Page 2: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

c. In class, we will discuss why we use abstract classes. In short, it is a way that we can generalize. Suppose we want to model birds and dogs; they have some things in common, for example they both have a name and they both can makeSound. Thus, we might define a superclass Animal to define these as common attributes as shown in the class diagram on the right. However, the way birds and dogs makeSound is different. Thus, we define makeSound as an abstract method and the Animal class as an abstract class. In UML, we indicate an abstract class and abstract methods using italics (when drawing by hand you can use double-quotes).

2. Do the following:

a. Establish a Workspace – Create a folder on your drive where you will put your lab or use an existing one.b. Run Eclipse – As the program begins to run, it will ask you to navigate to the Workspace you want to use.c. Create a Project – Create a Java project with the name, lab04_lastNameFirstInitial, e.g. lab04_gibsond.

3. Create some animals – Do the following:

a. Create a package named animals.b. Create a class named Animal and replace everything in the class (except the package statement at the top)

with:

public abstract class Animal {private String name;

public Animal(String name) {this.name = name;

}

public String getName() {return name;

}

public abstract String makeSound();}

c. Create a class named Dog and replace everything in the class (except the package statement at the top) with:

public class Dog extends Animal {public Dog(String name) {

super(name);}

public String makeSound() {return "Bark";

}}

2

Page 3: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

d. Create a class named Bird and replace everything in the class (except the package statement at the top) with:

public class Bird extends Animal {public Bird(String name) {

super(name);}

public String makeSound() {return "Chirp";

}}

e. Create a class named Driver and replace everything in the class (except the package statement at the top) with:

public class Driver {public static void main(String[] args) {

Dog d = new Dog("Wu");String msg = d.getName() + " " + d.makeSound() + "s";System.out.println(msg);

Bird b = new Bird("Tweety");msg = b.getName() + " " + b.makeSound() + "s";System.out.println(msg);

}}

f. Run and observe the output.

g. Since a Dog is-a Animal we can use Animal as a reference type when creating a Dog (or Bird). Add these lines to the end of main, run, and observe the output:

Animal a1 = new Dog("Lucky");msg = a1.getName() + " " + a1.makeSound() + "s";System.out.println(msg);

Animal a2 = new Bird("Kiwi");msg = a2.getName() + " " + a2.makeSound() + "s";System.out.println(msg);

h. Add this line to the end of main:

Animal a3 = new Animal("Shorty"); Note the compile error. This is important: you can not create an instance of an abstract class. Now, comment that line out.

3

Page 4: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

4. Add a polymorphic method to process animals – Do the following:

a. Add this method to the Driver class:

public static void printAnimal(Animal a) {String msg = a.getName() + " " + a.makeSound() + "s";System.out.println(msg);

}

Note that this method accepts an Animal. However, a Bird is-a Animal and so is a Dog so we can pass either of these to this method.

b. Add these lines to the end of main, run, and observe the output

System.out.println("Calling polymorphic method");printAnimal(d);printAnimal(b);printAnimal(a1);

Note that we can pass a Dog or a Bird to the method.

5. Casting – Do the following:

a. Add this method to the Driver class:

public static void whatIsIt(Animal a) {if( a instanceof Dog) {

Dog dog = (Dog)a;System.out.println("I'm a Dog named " + dog.getName());

}else if(a instanceof Bird) {

Bird bird = (Bird)a;System.out.println("I'm a Bird named " + bird.getName());

}}

Note that we can cast objects just as we did in Chapter 11.

b. Add these lines to the end of main, run, and observe the output

System.out.println("Casting");whatIsIt(a1);whatIsIt(a2);

4

Page 5: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

Stage 2 - Interfaces

In this stage we will consider the concept of interfaces.

6. (Read, no action required).

a. An interface in Java is very similar to an abstract class, except that all methods are abstract. None of the behaviors are implemented and it can’t define any instance variables. Thus, an interface is simply a specification of behavior.

b. Study the figure below and note the following:

We use the interface modifier to define an interface. We can declare the methods in an interface as abstract, but we don’t have to because by default all

methods in an interface are abstract. We use the implements keyword to denote that a class is implementing an interface. The Bird2 class must implement the (abstract) fly method.

c. An interface generally follows the is-a rule, e.g. a Bird is-a Flyer. However, many times it is easier to think about it as is-able-to, or can-do, or is-kind-of.

d. We will say more about when to use an abstract class and when to use an interface in class.

e. In UML, a hollow triangle with a dashed line is used to indicate that a class is implementing an interface as shown on the right.

5

Page 6: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

7. Do the following:

a. Copy the animals package and paste it giving it the new name, animals2.

b. Create a new interface (in the animals2 package) by choosing: File, New, Interface and supplying the name, Flyer.

c. Add the abstract method:

public String fly();

Note that all methods in an interface are abstract so you do not need to add the abstract modifier. However, you can if you want. Similarly, all methods in an interface are public and so the scope modifier can be left off as well (I generally leave off the abstract, but do use public).

d. Next, we will create the Bird2 class that implements the Flyer interface. Do the following:

i. Select the animals2 node in the Package Explorer.ii. Choose: File, New, Class

iii. Supply the Name, Bird2 and then choose the Add button:

iv. Type Flyer and choose OK.

6

Page 7: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

v. Choose Finish and the Bird2 class should be open and appear as shown on the right. Note that the required method(s) are automatically supplied with a default implementation.

e. Add a private string name instance variable, a getter, and a constructor that accepts the name to the Bird2 class.

private String name;

public Bird2(String name) {this.name = name;

}

public String getName() {return name;

}

f. Remove the code in the fly method and replace with:

return "flap-flap";

8. Now we will test the Bird. Do the following:

a. Open Driver (in the animals2 package) and replace everything in the class (except the package statement at the top) with:

public class Driver {public static void main(String[] args) {

Bird2 b = new Bird2("Castro");String msg = b.getName() + ", " + b.fly();System.out.println(msg);

}}

b. Run and verify the output.

c. Add this code to the bottom of main:

Flyer flyer = new Bird2("Wendy");flyer.getName();System.out.println(flyer.fly());

Notice that a compile error occurs. We are using Flyer as the reference type for creating a Bird2 which is fine. However, the Flyer interface does not define a getName method. This illustrates what we said earlier that the reference type (Flyer) determines which methods are accessible.

7

Page 8: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

d. Comment out the line from above that give the compile error, run, and verify the output.

e. We can cast objects just the same way as we did in the last chapter. Add this code to the bottom of main, run, and verify the output.

System.out.print("Casting a flyer: ");if(flyer instanceof Bird2) {

Bird2 b2 = (Bird2)flyer;msg = b2.getName() + ", " + b2.fly();System.out.println(msg);

}

9. A class in Java can implement any number of interfaces. We will implement the Flyer and Swimmer interfaces and in the Duck class as shown on the right. Thus, the Duck class will implement both the Flyer and the Swimmer interfaces. Do the following:

a. Create a new interface by choosing: File, New, Interface and supplying the name, Swimmer.

b. Add the abstract methods:

public String swim();public String dive();

c. Create a new class named Duck that implements both Flyer and Swimmer as shown below (Remember to use the Add button). When done, choose Finish.

8

Page 9: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

d. Implement the methods in the Duck class as shown below.

public class Duck implements Swimmer, Flyer {

@Overridepublic String fly() {

return "duck flying";}

@Overridepublic String swim() {

return "duck swimming";}

@Overridepublic String dive() {

return "duck diving";}

}

e. Add these lines to the end of main, run, and verify the output:

Duck duck = new Duck();System.out.println(duck.fly() + ", " + duck.swim() + ", " + duck.dive());

10. (Read, no action required) Classes in Java can extend one superclass and implement any number of interfaces. We will code the system shown in the class diagram on the right.

11. Do the following:

a. Open the Bird class (not Bird2) in the animals2 package.

b. Add this snippet of code to the end of the Bird class signature:

implements Flyer

c. Notice that a compile error occurs. Click the red X as shown on the right and then double-click “Add unimplemented methods”:

d. The fly method will be created with a default implementation. Replace the code there with:

return "bird flap-flap";

e. Add this import statement to the top of Driver class:

import java.util.ArrayList;

9

Page 10: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

f. Add this code to the bottom of main in the Driver class.

System.out.println("\nDogs and Birds: ");ArrayList<Animal> animals = new ArrayList<>();Animal a1 = new Dog("Rufus");animals.add(a1);Animal a2 = new Bird("Tweedledee");animals.add(a2);

for(Animal a : animals) {String msg2 = "name: " + a.getName() + "\n";msg2 += "makeSound: " + a.makeSound();

if(a instanceof Flyer) {Flyer f = (Flyer)a;msg2 += "\n" + "fly: " + f.fly();

}System.out.println(msg2);

}

Note that we can cast an object to use an interface as the reference type. In the code above, we check to see if a is-a Flyer and if it is we cast it and call the fly method.

g. Run and verify the output.

Stage 3 - The Comparable Interface

In this stage we will study the Comparable interface which is part of the Java API.

12. (Read, no action required).

a. The Java API provides the Comparable interface which is used to compare two objects to see which is larger, smaller, or if they are the same. The definition of the interface is:

public interface Comparable<E> { public int compareTo( E o );

}

compareTo is an instance method and should compare this object (the reference to the instance) to the argument, o (we will discuss the generic type parameter <E> shortly). The return value is an integer and has this meaning:

Return Whena negative integer this < ozero this == oa positive integer this > o

10

Page 11: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

b. The String class implements the Comparable interface. For example,

String x = "Atlanta";String y = "Denver";

int diff1 = x.compareTo(y);

returns -3 which means that Atlanta is “less than” Denver. The compareTo method is only required to return a negative integer (any) when x is less than y. However, the String class returns -3 in this case to indicate that the first place that the two strings differ is 3 characters apart (e.g. A and D)

c. Why is this important? Remember that we can sort a list of Strings:

ArrayList<String> cities = new ArrayList<>(Arrays.asList("NYC", "ATL", "DEN"));Collections.sort(cities);String min = Collections.min(cities);String max = Collections.max(cities);

The sort method requires that the items in the list being sorted implement the Comparable interface. Thus, the sort method calls compareTo on the individual items so that it can put them in order. The same is true of the min and max methods. There are other important classes and methods in the Java API that rely on Comparable.

13. Compare Strings – Do the following:

a. Create a package named comparable_examples.

b. Create a class named Examples1 and replace everything in the class (except the package statement at the top) with:

public class Examples1 {

public static void main(String[] args) {compareStrings();

}

public static void compareStrings() {String x = "Atlanta";String y = "Denver";String z = new String("Atlanta");

System.out.println("x=" + x + ", y=" + y + ", z=" + z);int diff1 = x.compareTo(y);System.out.println("x.compareTo(y)=" + diff1);int diff2 = y.compareTo(z);System.out.println("y.compareTo(z)=" + diff2);int diff3 = x.compareTo(z);System.out.println("x.compareTo(z)=" + diff3);

}

}

c. Run and verify the output.11

Page 12: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

14. Compare Boxes – Do the following:

a. (Read, no action required). Suppose we have a Box class:

public class Box {int x, y, z;double volume;

public Box(int x, int y, int z) {this.x = x;this.y = y;this.z = z;this.volume = x*y*z;

}}

and we want to be able to sort a list of boxes based on their volume. What we need to do is have the Box class implement the Comparable interface as shown in the class diagram on the right and have the compareTo method compare the volumes:

public class Box implements Comparable<Box> {

...

@Overridepublic int compareTo(Box other) {

if(this.volume < other.volume)return -1; // this is smaller

else if(this.volume > other.volume)return 1; // this is larger

elsereturn 0; // same

}

}

The specification for how compareTo works is that it simply return a “negative integer” if this is smaller than other (and a “positive integer” if this is larger, and “0” if they are the same). So, we can write compareTo in a much more succinct fashion as shown below:

@Overridepublic int compareTo(Box other) {

return this.volume - other.volume;}

12

Page 13: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

b. Create a class named Box and replace everything in the class (except the package statement at the top) with:

public class Box implements Comparable<Box> {int x, y, z;int volume;

public Box(int x, int y, int z) {this.x = x;this.y = y;this.z = z;this.volume = x*y*z;

}

@Overridepublic int compareTo(Box other) {

return this.volume - other.volume;}

@Overridepublic String toString() {

return "Box: x=" + x + ", y=" + y + ", z=" + z + ", vol=" + volume;}

}

c. Add these imports to the top (below the package statement) of the Examples1 class:

import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;

d. Add this method to the Examples1 class:

public static void sortBoxes() {System.out.println("\nSort Boxes");ArrayList<Box> boxes = new ArrayList<>(Arrays.asList(new Box(5,5,5), new

Box(2,2,5), new Box(3,3,3)));Collections.sort(boxes);Box min = Collections.min(boxes);Box max = Collections.max(boxes);

System.out.println("smallest box: " + min);System.out.println("largest box: " + max);System.out.println("sorted boxes: " + boxes);

}

e. Add this line to the bottom of main in Examples1:

sortBoxes();

f. Run and verify the output. The output should be as you expect; however, we need to do one more thing to the Box class to guarantee that it works correctly.

13

Page 14: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

15. Compare Boxes, override equals – Do the following:

a. (Read, no action required). Java’s documentation recommends that if you implement compareTo, then it should be consistent with equals. Remember that the equals method is inherited from the Object class. Thus, the Box class above should also override the equals method:

@Overridepublic boolean equals( Object o ) {

return this.volume == ((Box)o).volume;}

b. Add the method above to the Box class.

c. Run and verify the output.

16. Compare Persons – Do the following:

a. (Read, no action required). Suppose we have a Person class that has a name field (String) and we want to be able to sort a list of Person objects on name. The equals and compareTo methods can be confusing at first. The name field is String which implements Comparable itself. Thus, we will use the name field’s equals and compareTo methods inside the overridden equals and compareTo methods in the Person class.

@Overridepublic int compareTo(Person other) {

return this.name.compareTo(other.name);}

@Overridepublic boolean equals( Object o ) {

return this.name.equals(((Person)o).name);}

b. Create a class named Person and replace everything in the class (except the package statement at the top) with:

public class Person implements Comparable<Person> {String name;

public Person(String name) {this.name = name;

}

@Overridepublic int compareTo(Person other) {

return this.name.compareTo(other.name);}

@Overridepublic boolean equals( Object o ) {

return this.name.equals(((Person)o).name);}

14

Page 15: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

@Overridepublic String toString() {

return "Person: name=" + name;}

}

c. Add this method to the Examples1 class:

public static void sortPersons() {System.out.println("\nSort Persons");ArrayList<Person> persons = new ArrayList<>(Arrays.asList(new

Person("Xav"), new Person("Ana"), new Person("Mimi")));Collections.sort(persons);Person min = Collections.min(persons);Person max = Collections.max(persons);

System.out.println("smallest person: " + min);System.out.println("largest person: " + max);System.out.println("sorted persons: " + persons);

}

d. Add this line to the bottom of main in Examples1:

sortPersons();

e. Run and verify the output.

15

Page 16: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

Stage 4 - The Cloneable Interface

In this stage we will study the Cloneable interface which is part of the Java API.

17. (Read, no action required). This is a review of a topic discussed previously in this class. In Java a variable can hold a reference to an object. For example, below we create an ArrayList with the reference x:

Then, we assign this reference x to the reference y:

Thus, we are creating a copy of the reference, not a copy of the object. Both variables reference (point to) the the same object. For example:

Thus, if we use one reference, say y to change the object and then use the other reference, say x to access the object, x will show the change – of course! Because x and y are pointing to the same object. For example, if we write:

Then both x and y reflect the change.

So, suppose you want to actually copy an ArrayList, how would you do that?

18. (Read, no action required). Java provides a mechanism for copying an object called cloning where a duplicate object is created. The Object class has a protected clone method which will clone any object that implements the Cloneable interface. As shown on the right, ArrayList inherits the clone method from the Object class and implements the Cloneable interface. Thus,

ArrayList<Integer> x,y;x = new ArrayList<>(Arrays.asList(5,2,7));y = (ArrayList<Integer>) x .clone() ;

results in two distinct copies of the object:

Note: a. The clone method works by creating a new object and copying all the field values from the existing one. b. The clone method returns an Object reference so we must cast it to the desired type.

16

Page 17: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

19. Copying a Reference to an ArrayList – Do the following:

a. Create a package named cloneable_examples.

b. Create a class named CloneExamples and replace everything in the class (except the package statement at the top) with:

import java.util.ArrayList;import java.util.Arrays;

public class CloneExamples {

public static void main(String[] args) throws CloneNotSupportedException {arrayListExample();

}

public static void arrayListExample() {// Copy a referenceArrayList<Integer> x,y;x = new ArrayList<>(Arrays.asList(5,2,7));

System.out.println("Copying the reference to an ArrayList<Int>:");ArrayList<Integer> ints = new ArrayList<>(Arrays.asList(5,2,7));ArrayList<Integer> ints2 = ints;

System.out.println(" Before change:");System.out.println(" ints :" + ints);System.out.println(" ints2:" + ints2);System.out.println(" int & int2 the same? " + (ints==ints2));

ints2.set(1, 99);

System.out.println("\n After ints2.set(1,99):");System.out.println(" ints :" + ints);System.out.println(" ints2:" + ints2);

}}

c. Run and verify the output.

20. Clone an ArrayList – Do the following:

a. Copy this code to the bottom of the arrayListExample method:

ints2.set(1, 2);

// Clone ArrayListSystem.out.println("\nCloning an ArrayList<Int>:");ints2 = (ArrayList<Integer>) ints .clone() ;

System.out.println(" Before change:");System.out.println(" ints :" + ints);System.out.println(" ints2 (clone):" + ints2);System.out.println(" int & int2 the same? " + (ints==ints2));

17

Page 18: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

ints2.set(1, 99);

System.out.println("\n After ints2.set(1,99):");System.out.println(" ints :" + ints);System.out.println(" ints2:" + ints2);

b. Run and verify the output.

21. (Read, no action required). If we want to allow a custom object to be cloned, we must do the following:

a. Implement the Cloneable interface. The Cloneable interface in Java is a marker interface which means that it specifies no methods, it just exists to tell the compiler an object can be cloned.

b. Override the clone method.

22. Clone a Dog – Do the following:

a. Create a class named Dog and replace everything in the class (except the package statement at the top) with:

public class Dog implements Cloneable {private String name;

public String getName() {return name;

}

public void setName(String name) {this.name = name;

}

@Overridepublic Object clone() throws CloneNotSupportedException {

return super.clone();}

@Overridepublic String toString() {

return "Dog name=" + name;}

}

Note the following about the clone method:

The Object class’s clone method is protected, so we override it giving it public accessibility. Otherwise, it could not be called. A good question is, “why is it protected in the Object class?”. It is done this way so that by default a custom object cannot be cloned, unless we override the clone method making it public as above.

The overridden clone method above simply calls the protected clone method in the Object class

18

Page 19: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

b. Copy this method into the CloneExamples class:

public static void personDogExample() throws CloneNotSupportedException {// Clone a DogSystem.out.println("\nClone a Dog");Dog d = new Dog();d.setName("Fido");

Dog d_clone = (Dog)d.clone();System.out.println(" dog :" + d + "\n dog_clone:" + d_clone);

System.out.println("\n After d_clone.setName('Waldo'):\n");d_clone.setName("Waldo");System.out.println(" dog :" + d + "\n dog_clone:" + d_clone);

System.out.println("\n dog & dog_clone the same? " + (d==d_clone));}

c. Add this line to the bottom of main:

personDogExample();

Note, when you add this line you will get a compilation error. Click the red X and then choose, “Add throws declaration.” (This will be explained in class).

d. Run and verify the output.

23. Clone a Person who has a Dog, Incorrectly – Do the following:

a. (Read, no action required). Suppose want to have a Person class that has-a Dog and that we want the Person to be cloneable. First, we will do exactly as we did above, the Person class will override clone in the same manner and implement Cloneable; however, it won’t work correctly.

b. Create a class named Person and replace everything in the class (except the package statement at the top) with:

public class Person implements Cloneable{private int age;private Dog dog;

public Person(int age, Dog dog) {super();this.age = age;this.dog = dog;

}

public Dog getDog() {return dog;

}

public void setDog(Dog dog) {this.dog = dog;

}

19

Page 20: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

public int getAge() {return age;

}

public void setAge(int age) {this.age = age;

}

@Overridepublic Object clone() throws CloneNotSupportedException {

return super.clone();}

@Overridepublic String toString() {

return "Person age=" + age + ", " + dog;}

}

c. Copy this code at the end of the the PersonDogExample method:

// Clone a Person who has a Dog, incorrectlySystem.out.println("\nClone a Person who has a Dog, incorrectly");

d = new Dog();d.setName("Fido");Person p = new Person(19,d);Person p_notClone = (Person)p.clone();

System.out.println(" p :" + p + "\n p_notClone:" + p_notClone);

System.out.println("\n After p_clone.getDog().setName('Gypsy'):\n");

d = p_notClone.getDog();d.setName("Gypsy");

System.out.println(" p :" + p + "\n p_notClone:" + p_notClone);

d. Run and verify the output. Study the code above carefully. At the conclusion this will be in memory:

Thus, we have cloned the Person but both objects point to the same Dog instance. In other words, we have not really cloned the Person object at all!

20

Page 21: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

24. Clone a Person who has a Dog, Correctly – Do the following:

a. (Read, no action required). Note what we said earlier about the clone method in the Object class:

“The clone method works by creating a new object and copying all the field values from the existing one.”

This works fine for primitive data types (e.g. age). However, as we saw earlier in this lab, when you copy a reference variable (e.g. dog) we get a copy of the reference, not a copy of the object. We say that Java’s clone method returns a shallow copy, not a true copy (clone). To remedy this we create a deep copy that requires a bit more work.

b. Copy the Person class and give it the name Person2.

c. Replace the code in in the Person2 class’s clone method with:

Person2 personClone = (Person2)super.clone();Dog dogClone = (Dog)dog.clone();personClone.setDog(dogClone);return personClone;

Study the code above carefully. We first clone the person (which is pointing to the same dog). Next, we clone the dog object inside the Person. Now we have a legitimate duplicate dog. Then, we set this dog clone into the person clone with the setDog method. To make a deep copy (as this is) we usually have to take a brute force approach.

d. Add this code to the end of the personDogExample method in the CloneExamples class:

// Clone a Person who has a Dog, correctlySystem.out.println("\nClone a Person who has a Dog, correctly");

d = new Dog();d.setName("Fido");Person2 p2 = new Person2(19,d);Person2 p2_Clone = (Person2)p2.clone();

System.out.println(" p2 : " + p2 + "\n p2_Clone: " + p2_Clone);

System.out.println("\n After p2_clone.getDog().setName('Gypsy'):\n");

d = p2_Clone.getDog();d.setName("Gypsy");

System.out.println(" p2 : " + p2 + "\n p2_Clone: " + p2_Clone);

21

Page 22: mypages.valdosta.edumypages.valdosta.edu/dgibson/courses/cs1302/labs/cs1…  · Web viewTo make this document easier to read, it is recommend that you turn off spell checking in

e. Run and verify the output. At the conclusion of this code memory will look like as shown below. Thus, we will have a legitimate clone:

You are done!

22