Presentation is loading. Please wait.

Presentation is loading. Please wait.

CS/ENGRD 2110 FALL 2016 Lecture 7: Interfaces and Abstract Classes

Similar presentations


Presentation on theme: "CS/ENGRD 2110 FALL 2016 Lecture 7: Interfaces and Abstract Classes"— Presentation transcript:

1 CS/ENGRD 2110 FALL 2016 Lecture 7: Interfaces and Abstract Classes

2 Announcements Attendance for this week’s recitation is mandatory!
A2 is due Today Get started on A3 – a method every other day

3 A Little Geometry! Shape x ____ y ____ Square area() size ____
Abstract Classes Shape x ____ y ____ Square area() size ____ Triangle area() base____ height ____ Circle area() radius __5__ Encourage the students to download the code for this online The goal is to incorporate an area method for all shapes Note that on this slide (and others), to simplify formatting, we show a variable as its name following by underlining, and we may put the value in the udnerline place (as done in one case here) x,y are coordinates that are for all shapes. Each subclass has its own relevant fields. Explain that Circle, Square, and Triangle all have different area() functions but Shape does not have one

4 Demo 1: Complete this function
Abstract Classes /** Return the sum of the areas of * the shapes in s */ static double sumAreas(Shape[] s) { } Operator instanceof and casting are required Adding new Shape subclasses breaks sumAreas Show them the code and how each of the subclasses have a function area but not in superclass Shape Point out how ugly the casting makes the function private static double sumAreas(Shape[] shapes){ int total = 0; for (int i = 0; i < shapes.length; i++) { if (shapes[i] instanceof Square) { total += ((Square) shapes[i]).area(); } else if (shapes[i] instanceof Triangle) { total += ((Triangle) shapes[i]).area(); } else if (shapes[i] instanceof Circle) { total += ((Circle) shapes[i]).area(); } return total; Discussion notes regarding the function: Not very extensible: if you try to add another subclass All methods using Shapes need to change Bugs appear if more subclasses are added and methods aren’t fixed Casting is ugly, verbose, and has potential for runtime errors Also! All different types of shapes have area, but superclass Shape doesn’t have a function area - a bit strange

5 A Partial Solution: Add method area to class Shape:
Abstract Classes Add method area to class Shape: public double area() { return 0; } public double area() { throw new RuntimeException(“area not overridden”); } Try to solve the casting problem: Ask for ideas. Solve our earlier problem - makes sumAreas(..) simple and clean, but has its own host of issues: Subclasses of Shape have to remember to override - easy to lose track of, cause bugs down the line Shapes that aren’t subclasses have 0 area, which would normally be incorrect Now add the RuntimeException: Gets even closer. Now we can’t call getArea on Shapes that aren’t subclasses. Still, subclasses of Shape have to remember to override - easy to lose track of, cause bugs down the line Makes a lot more runtime errors – compile time (syntax) errors are easier to catch and fix

6 Problems not solved Shape s= new Shape(...); Should be disallowed
Abstract Classes What is a Shape that isn’t a Circle, Square, Triangle, etc? What is only a shape, nothing more specific? Shape s= new Shape(...); Should be disallowed 2. What if a subclass doesn’t override area()? Can’t force the subclass to override it! Incorrect value returned or exception thrown.

7 Solution: Abstract classes
public abstract class Shape { public double area() { return 0; } Abstract class Means that it can’t be instantiated. new Shape() illegal This solves thefirst problem - by making Shape abstract, we don’t have to worry about instantiating it. Cannot create an object of class Shape because use of new-expression is illegal. So every Shape object is truly a Circle, Square, Triangle, or some other subclass.

8 Solution: Abstract methods
Abstract Classes public abstract class Shape { public abstract double area(); } Can also have implemented methods Place abstract method only in abstract class. Semicolon instead of body. This solves the second problem. An abstract method must be overridden in every subclass -- not doing so is a compile time error --program us illegal. An abstract method doesn’t have a body -- just method header then semicolon. Abstract method Subclass must override.

9 Demo 2: A better solution
Abstract Classes We modify class Shape to be abstract and make area() an abstract method. Abstract class prevents instantiation of class Shape Abstract method forces all subclasses to override area() Make Shape abstract, the problem of area() is now solved Go back and make the first demo look a lot cleaner. Note: You don’t have to go over those bullet points, the next slide handles them for emphasis. When you demo, it is a good idea to tell them does import java.util.Arrays; public abstract class Shape implements Comparable<Shape> { private int x; private int y; /** Constructor: a shape with bounding box top left (x, y). */ public Shape(int x, int y) { this.x= x; this.y= y; } /** = area of this Shape. */ public abstract double area(); /** = < 0, 0, or > 0 depending on whether this Shape's * area is smaller, than, equal to, or grater than s's area*/ int compareTo(Shape s) { double diff= area() - s.area(); return (diff == 0 ? 0 : diff < 0 ? -1 : +1); /** = repr of this Shape, giving its position. */ public String toString() { return "(" + x + ", " + y + ")"; /** Method main to test things. */ public static void main(String[] args) { Shape[] shapes= new Shape[5]; shapes[0]= new Circle(3, 4, 2); shapes[1]= new Circle(1, 2, 15); shapes[2]= new Square(0, 0, 20); shapes[3]= new Square(0, 0, 5); shapes[4]= new Square(0, 0, 2); System.out.println("unsorted: " + Arrays.toString(shapes)); Arrays.sort(shapes); System.out.println(" sorted: " + Arrays.toString(shapes));

10 Abstract Classes, Abstract Methods
Cannot instantiate an object of an abstract class. (Cannot use new-expression) A subclass must override abstract methods. Why? Java requires this so that the following doesn’t happen. If subclasses didn’t override the abstract method, we could have a situation where the method gets called but it has no implementation to use If we could instantiate an object of an abstract class and tried to call one of the abstract methods, it would have no implementation to use

11 Interfaces

12 Problem Where is the best place to implement whistle()? Animal Mammal
Interfaces Where is the best place to implement whistle()? Animal Mammal Bird Whistler If we were to implement a method whistle(), where is the best place to implement whistle? Some of our animals like Human and Parrot should be able to whistle but Dog should not. Two problems: We could implement whistle() in a superclass, but that doesn’t really make sense because not all animals, mammals, or birds are whistlers. We could implement whistle() in just Human and Parrot, but then we would have to do that ugly casting again in order to run whistle(). It would be great to have a second class Whistler that we could extend! Human could just inherit from Whistler and Mammal. Human Dog Parrot

13 No multiple inheritance in Java!
Interfaces class Whistler { void breathe() { … } } class Animal { class Human extends Animal, Whistler { new Human().breathe(); Which breathe() should java run in class Human? Can extend only one class! Java does not allow this because it doesn’t know which method breathe to call. C++ has always had multiple inheritance and it’s always been a problem.

14 Why not make it fully abstract?
Interfaces class abstract Whistler { abstract void breathe(); } class abstract Animal { class Human extends Animal, Whistler { Java doesn’t allow this, even though it would work. Instead, Java has another construct for this purpose, the interface Use abstract classes instead? Seems okay because method bodies are not given. But Java does not allow this, because abstract classes can still have similarly named non-abstract methods. Instead, Java has a construct, the interface, which is like an abstract class but has more restrictions.

15 Solution: Interfaces public interface Whistler { void whistle();
methods are automatically public and abstract fields are automatically public, static, and final (i.e. constants) public interface Whistler { void whistle(); int MEANING_OF_LIFE= 42; } class Human extends Mammal implements Whistler { An interface is like a fully abstract class but has a slightly different syntax. An interface can contain type signatures for methods, just like abstract methods in abstract classes, but they have to be public. An interface can contain fields, but they have to be public, static, and final and they have to contain an initializer. So they are really just constants. Emphasize again: An interface is like an abstract class in which all methods are abstract and all fields are constants. It’s just a different syntax. Must implement all methods in the implemented interfaces

16 Multiple interfaces public interface Singer { void singTo(Human h); }
Classes can implement several interfaces! They must implement all the methods in those interfaces they implement. public interface Singer { void singTo(Human h); } class Human extends Mammal implements Whistler, Singer { NOTE If someone asks about conflicting constants in interfaces, Java will actually have an compile-time error due to ambiguity. So you would need to call the constant you want from the interface like Whistler.MEANING_OF_LIFE or Singer.MEANING_OF_LIFE. Similarly for conflicting return types for methods of the same name, java will say that the return type is incompatible with one of the interfaces. Must implement singTo(Human h) and whistle()

17 Solution: Interfaces Interfaces Interface Whistler offers promised functionality to classes Human and Parrot! Animal Mammal Bird Whistler Implementing an interface allows a class to become more formal about the behavior it promises to provide. Interfaces form a contract between the class and the outside world, and this contract is enforced at build time by the compiler. If your class claims to implement an interface, the class will compile only if all methods defined by that interface are overridden in the class. Human Dog Parrot

18 Casting to an interface
Interfaces Human h= new Human(); Object o= (Object) h; Animal a= (Animal) h; Mammal m= (Mammal) h; Singer s= (Singer) h; Whistler w= (Whistler) h; All point to the same memory address! Object Animal Whistler Mammal Singer There are six perspectives of the same Human object. From each perspective, you can call a method m() (say) only if it is defined in that perspective or above it; otherwise, the call is illegal. This ensures that a method to be called actually exists at runtime. But of course the object does NOT change when one casts. Human

19 Casting to an interface
Interfaces Human h= new Human(); Object o= h; Animal a= h; Mammal m= h; Singer s= h; Whistler w= h; Object Automatic up-cast Animal Whistler Mammal Singer Note that explicit upcasts are unnecessary. Explicit downcasts are necessary --and they should be done only if it is KNOWN that the cast will work (use instanceof to check that). Note that c instanceof C is true iff c has a partition called C. For the object shown on this slide, h instance of C is true for C being Whistler, Human, Mammal, Singer, Animal, and Object. Forced down-cast Human

20 Casting up to an interface automatically
Interfaces class Human … implements Whistler { void listenTo(Whistler w) {...} } Human h = new Human(...); Human h1= new Human(...); h.listenTo(h1); Object Animal Whistler Mammal Arg h1 of the call has type Human. Its value is being stored in w, which is of type Whistler. Java does an upward cast automatically. It costs no time; it is just a matter of perception. When h.listenTo(h) or h.listenTo(w) gets called, it calls the listenTo method declared in Human. (“Bottom-up rule”) w.listenTo(w) doesn’t compile because a Whistler object does not have a listenTo method. Whenever we call upon w, the compiler knows that it can call upon the methods that were declared in interface Whistler. Human

21 Demo 3: Implement Comparable<T>
Implement interface Comparable in class Shape: public interface Comparable<T> { /** = a negative integer if this object < c, = 0 if this object = c, = a positive integer if this object > c. Throw a ClassCastException if c can’t be cast to the class of this object. */ int compareTo(T c); } In class Shape, we can write a method compareTo that orders Shapes based on their areas. For example, if Shape object s1 has a smaller area than Shape object s2, s1.compareTo(s2) should return a negative number. class Shape implements Comparable<Shape> { public int compareTo(Shape s) { double diff= area() - s.area(); if (diff < 0) { return -1; } else if (diff == 0) { return 0; } else { return 1; }

22 Shape implements Comparable<T>
public class Shape implements Comparable<Shape> { ... /** … */ public int compareTo(Shape s) { double diff= area() - s.area(); return (diff == 0 ? 0 : (diff < 0 ? -1 : +1)); } At this point, in your Demo, change class Shape to implement Comparable<T> as shown on this slide, adding method compareTo and implementing Comparable<Shape>. You should then be able to run method main and show them that the sort works. Note: It would be nice to write compareTo using just: return area() - s.area() but the expression is a double. And if we try to cast it to an int, using return (int)(area() - s.area()); it doesn’t give the right answer is the area different is between -1 and 1 (non-inclusive).

23 Beauty of interfaces Boolean Byte Double Integer
Arrays.sort sorts an array of any class C, as long as C implements interface Comparable<T> without needing to know any implementation details of the class. Classes that implement Comparable: Boolean Byte Double Integer String BigDecimal BigInteger Calendar Time Timestamp and 100 others All 110 very diverse/different classes that implement Comparable just need to use one method! (Arrays.sort) Interfaces stop us from needlessly writing 110 different sort implementations! If YOUR class C (say) implements Comparable, thus providing a method that gives an ordering to objects of the class, you can use Arrays.sort to sort arrays C[].

24 String sorting Arrays.sort(Object[] b) sorts an array of any class C, as long as C implements interface Comparable<T>. String implements Comparable, so you can write String[] strings= ...; ... Arrays.sort(strings); Because of interfaces, we need only one sort method, which just relies on compareTo. As long as Arrays.sort can cast elements to type Comparable, it can reliably call method compareTo. During the sorting, when comparing elements, a String’s compareTo function is used

25 And Shape sorting, too! Arrays.sort(Object[] b) sorts an array of any class C, as long as C implements interface Comparable<T>. Shape implements Comparable, so you can write Shape[] shapes= ...; ... Arrays.sort(shapes); Because of interfaces, we need only one sort method, which just relies on compareTo. As long as Arrays.sort can cast elements to type Comparable, it can reliably call method compareTo. During the sorting, when comparing elements, a Shape’s compareTo function is used

26 Abstract Classes vs. Interfaces
Abstract class represents something Sharing common code between subclasses Interface is what something can do A contract to fulfill Software engineering purpose Similarities: Can’t instantiate Must implement abstract methods Later we’ll use interfaces to define “abstract data types” (e.g. List, Set, Stack, Queue, etc) (If you have time) go through the points in the context of the previous examples of Humans/Whistlers and Shapes. SoftwareeEngineering: specify and enforce boundaries between different parts of a team project Because they will have had some exposure to Lists, you can say that if they implement interface List<T>, it allows a user to have a guarantee that their list implementation will have those List methods. It doesn’t say anything about the implementation (backing array vs. objects and pointers). It just needs to satisfy the specification. Else, there will be a compiler error.


Download ppt "CS/ENGRD 2110 FALL 2016 Lecture 7: Interfaces and Abstract Classes"

Similar presentations


Ads by Google