Concept Review Day 2: abstract class, interface, inheritance, and polymorphism Page 1 Passing arguments: Arguments are passed in Java by copy. a) Primitive data types: like x=5, the value that is copied if x is sent as an actual parameter is 5 public static void myMethod(int a) { // any changes you do here to the variable a does not affect the value of x // since a is a copy of x a=10; // the x is not affected and is still 5 } //… somewhere in main for example int x = 5; myMethod(x); System.out.println(x); // The output is 5 b) Complex (object) data types: like p = new Point(2,5), the value that is copied is the actual address of p (So for example if the formal parameter is q then p and q point to the same object, so p==q is true) public static void myMethod(Point q) { //any changes I do to the content of q are seen by p //since p and q point to the same memory address q.setX(3); //now p.x is also 3 q = new Point(10,15); //this will make q point to a different place in memory // than p so now this change is not seen by p anymore q.setX(20); //this changes the x of q after q points to a different object // than p so that p doesn’t see this change either } //… somewhere in main for example Point p = new Point(2,5); myMethod(p); // p has (3, 5): 3 because q was pointing to p. // 5 because p.y was in the old p, unchanged. Practice 1) What is the output of the following code? Makes a copy Directly changes public static void main(String[] args){ int, double, Objects, arrays, int index = 2; boolean ArrayLists, int[] array = {1, 2, 3, 4, 5}; all the data structures mystery(array, index); String StringBuffer System.out.println(array[index]+" is at "+ index); } public static void mystery(int[] list, int index){ list[index] = -1; index += 1; array is an Object, passed by reference. Any changes made in the System.out.println(index); method are persistent. list[index] = -1; } Output: 3 -1 is at 2 More MC on this? int is a primitive type, passed by copy. Changes made in the method are not persistent. index += 1; Exception: Strings are Objects, but they are immutable, so they act as if they were passed by copy. Concept Review Day 2: abstract class, interface, inheritance, and polymorphism public interface Shape { public abstract double findArea(); } public abstract class Polygon implements Shape { private int numOfSides; public Polygon() { numOfSides = 0; } public Polygon(int sides) { numOfSides = sides; } public int getSides() { return numOfSides; } public abstract int findPerimeter(); public String toString() { return "Number of sides = " + numOfSides; } } // Client class public class PolygonDriver{ public static void main(String[] args){ Rectangle rect_1 = new Rectangle(5, 10); Polygon rect_2 = new Rectangle(5, 10); Shape rect_3 = new Rectangle(5, 10); System.out.println(rect_1); System.out.println(rect_2); System.out.println(rect_3); System.out.println("rect_1 == rect_2: " + rect_1.equals(rect_2)); } } Output: Number Number Number rect_1 of of of == sides = sides = sides = rect_2: 4, length = 5 and width = 10 4, length = 5 and width = 10 4, length = 5 and width = 10 true Page 2 public class Rectangle extends Polygon { private int myLength, myWidth; public Rectangle(int length, int width) { super(4); myLength = length; myWidth = width; } public int getLength() { return myLength; } public int getWidth() { return myWidth; } public void setLength(int length) { myLength = length; } public void setWidth(int width) { myWidth = width; } public boolean equals(Object other) { if(other instanceof Rectangle){ Rectangle oth = (Rectangle)other; return myLength == oth.myLength && myWidth == oth.getWidth(); } else return false; } public int findPerimeter() { return myLength * 2 + myWidth * 2; } public double findArea() { return myLength * myWidth; } public String toString() { return super.toString() + ", length = " + myLength + " and width = " + myWidth; } } What is the purpose of an interface? What is the purpose of an abstract class? Why does Polygon have to be marked “abstract”? Polygon has two abstract methods: findArea(inherited) and findPerimeter Rectangle is-a Polygon and is-a Shape: See blue highlight in driver -- polymorphism Rectangle inherits all public methods, but not the private instance variables, from Polygon. What does Square inherit from Rectangle? toString() is overridden in Polygon and in Rectangle (see super.toString()). The driver sees and uses the overridden version. equals() is overridden in Rectangle so that rect_1 equals rect_2 in driver Casting happens in the equals(Object other) method. First you cast, then you check the fields to see if they are equal. Concept Review Day 2: abstract class, interface, inheritance, and polymorphism Page 2 continued Practice 2) Write Rectangle’s subclass Square. Square class has one argument constructor which passes the side length. It also has one accessor and one modifier methods. Note that Square does not need any additional instance variable. Note: Square’s data is stored in the Rectangle class! public class Square extends Rectangle { public Square(int sideLength) { super(sideLength, sideLength); } public int getSide() { return getLength(); } public void setSide(int sideLength) { setLength(sideLength); // NO!: setWidth(sideLength); } } myLength = sideLength; //does Square have direct access to myLength and myWidth? – NO! A UML diagram of the class hierarchy: is-a Shape Polygon is-a PolygonDriver has-a Rectangle is-a Square Concept Review Day 2: abstract class, interface, inheritance, and polymorphism Concrete class Regular class which has no abstract method. Has only concrete (implemented) methods Abstract class Page 3 Interface Is used to define a class that will be used only to build new classes. Not a class. No abstract keyword in interface header. Is used when you know quite a bit about an object and what you want the object to do, but yet there are still a few unknowns. a list of what methods are available. Has at least one abstract method. Has only abstract methods. Any concrete subclass that extends a super abstract class must implement all methods defined as abstract in the super class. T / F: Possible to instantiate an object from a concrete class Subclass extends Superclass Ex) Point, Rectangle T / F: Possible to instantiate an object from an abstract class T / F: Possible to instantiate an object from an interface Subclass extends Superclass Subclass implements interface Subinterface extends Superinterface Ex) Polygon Ex) Comparable, Shape Inheritance: One object acquires all properties (public instance variables and methods) of its parent object. Constructors are not inherited. Polymorphism: A superclass declaration can refer to a subclass object. When the program actually runs, it will run according to the directions in the subclass. Superclass ways to instantiate an object: Shape one = new Rectangle(4, 5); Rectangle two = new Square(5); Shape three = new Square(7); Practice 3) Choose legal or illegal for each statement below: Polygon rect_2 = new Rectangle(5, 10); //superclass reference to a subclass object Legal / illegal: Rectangle abcd = new Polygon(4); Legal / illegal: rect_2.setWidth(3); “thinks it is a polygon” Legal / illegal: int num = rect_2.getSides(); “polygon has getSides(). Rectangle inherits polygon’s version.” Legal / illegal: Polygon[] shapes3 = {new Rectangle(5, 3), new Square(4), new Polygon(4)}; Legal: an array of abstract references illegal: new Polygon() Concept Review Day 2: abstract class, interface, inheritance, and polymorphism Page 4 Practice 4) Consider the following incomplete classes: public abstract class Animal { public Animal() { /* implementation not shown public abstract void eat(); } */ public class Bear extends Animal { public Bear() { /* implementation not shown */ } public void eat() { /* implementation not shown */ } } } Which of the following statements will compile without errors? I. Animal joe = new Animal(); II. Animal smokey = new Bear(); III. Bear Teddy = new Animal(); (A) (B) (C) (D) (E) I only (no, because you can’t instantiate an abstract class Animal) II only (yes, because it is a superclass reference to a subclass object) I and II II and III I, II, and III Practice 5) If class C implements interface I and has a no-arg constructor, which of the following statements results in a syntax error? (A) (B) (C) (D) C x = new C(); I x = new C(); C[] x = new C[10]; I[] x = new I[10]; //makes an array for 10 references. You instantiate the actual objects later. That’s okay. (E) All of the above compile with no errors. Practice 6) Which of the following statements about constructors is NOT true? (A) (B) (C) (D) (E) All constructors must have the same name as the class they are in. Constructor’s return types must be declared void. A class may have a constructor that takes no arguments. A constructor is invoked when a program creates an object with the new operator. A constructor of a subclass can call a constructor of its superclass using the Java reserved word super. Concept Review Day 2: abstract class, interface, inheritance, and polymorphism Page 5 Practice 7) Consider the following classes: public class A { private int myNum; public A (int x) { myNum = x ; } public int getNumber() { return myNum; } public String getLetters() { return "A"; } public String getMessage() { return getLetters() + "-" + getNumber(); } } public class AB extends A { public AB (int x) { super(x + 1); } public int getNumber() { return super.getNumber() + 1; } public String getLetters() { return "AB"; } } What is the output of the following code segment? A test = new AB(0); // “thinks it is an A, but A’s methods all do AB stuff” System.out.print( test.getMessage() ); (A) A-0 (B) A-1 (C) A-2 (D) AB-1 (E) AB-2 AB’s constructor calls A’s constructor, passing 0+1. Therefore A’s myNum = 1 A’s getMessage() calls getLetters(), which has been overridden. That getLetters() returns ABA’s getMessage() then calls getNumbers(), which has been overridden, but that calls the super’s getNumbers() + 1, which returns 2 Concept Review Day 2: abstract class, interface, inheritance, and polymorphism Page 6 Practice 8) public abstract class House implements Comparable<House> { private int mySize; public House(int size) { mySize = size; } public int getSize() { return mySize; } public void setSize(int size) { mySize = size; } public int compareTo(House other) { return getSize() - other.getSize(); } public abstract int getPrice(); } public class HouseForSale extends House { private int myPrice; public HouseForSale( int size, int price) { // < missing statement > myPrice = price; } public int getPrice() { return myPrice; } public int compareTo(House other) { return getPrice() - ((HouseForSale)other).getPrice(); } //. . . other constructors, methods, and fields not shown Which of the following is the most appropriate replacement for < missing statement > in HouseForSale's constructor? (A) (B) (C) (D) (E) mySize = size; setSize(size); super.setSize(size); super(size); super = new House(size); Concept Review Day 2: abstract class, interface, inheritance, and polymorphism Page 7 Practice 9) Consider the following classes: public class A extends Object //every class automatically extends Object { //how else do get equals, toString, hashCode? public A() { super(); //hidden automatic super is here, too methodOne(); } public void methodOne() { System.out.print("A"); } } public class B extends A { public B() { super(); //hidden automatic super System.out.print("*"); } public void methodOne() { System.out.print("B"); } } What is the output when the following code statement is executed? A obj = new B(); (A) (B) (C) (D) (E) * *A *B A* B* If there is no explicit super(), then Java puts in a hidden, automatic call to super() which is called before anything else. B’s constructor therefore calls A’s constructor, which calls methodOne, which is overridden, so that it prints B Then B’s constructor prints * Concept Review Day 2: abstract class, interface, inheritance, and polymorphism Page 8 Practice 10) Consider the following interface TV and class myTV: public interface TV { abstract void tuneTo(String channel); } public class MyTV implements TV { private ArrayList<String> myFavoriteChannels; public MyTV(ArrayList<String> channels) { /* implementation not shown */ } public void tuneTo(int k) { /* implementation not shown */ } public void tuneTo(int k, String name) { /* implementation not shown */ } } Which of the following best describes the compiler errors reported for the statements that are shown? (A) (B) (C) (D) (E) In the TV interface, the tuneTo declaration is missing the keyword public. MyTV should be declared abstract because it does not define tuneTo(String). tuneTo is defined more than once in MyTV. Cannot convert int to String in the tuneTo method in MyTV. Two errors: (1) tuneTo is defined more than once and (2) cannot convert int to String in the tuneTo(int) method in MyTV. Practice 11) Consider the hierarchy of classes shown in the following diagram. Concept Review Day 2: abstract class, interface, inheritance, and polymorphism public class Cat extends Pet { public Cat(String name) { super(name); } public String speak() { return "meow"; } } Page 9 Concept Review Day 2: abstract class, interface, inheritance, and polymorphism public class LoudDog extends Dog { public LoudDog(String name) { super(name); } public String speak() { return super.speak() + " " + super.speak(); } } Page 10 Concept Review Day 2: abstract class, interface, inheritance, and polymorphism Page 10 continued // Assume that petList is for the Pet type: private ArrayList<Pet> petList; //Question: if the Pet is a Dog, Cat, or LoudDog, do you need to cast? -- NO! public void allSpeak() { for(int i = 0; i < petList.size(); i++) { Pet p = petList.get(i); System.out.println(p.getName() + " " + p.speak()); } } using for-each loop: public void allSpeak() { for( Pet p : petList ) System.out.println(p.getName() + " " + p.speak()); }