Enhanced Class Design -Introduction We now examine several features of class design and organization that can improve reusability and system elegance We will focus on: abstract classes & polymorphism Extending Interfaces 1 Nested Classes In addition to a class containing data and methods, it can also contain other classes A class declared within another class is called a nested class Outer Class Nested Class 2 Nested Classes A nested class has access to the: variables and methods of the outer class, even if they are declared private This makes the implementation of the classes easier because they can easily share information 3 Protecting the inner class The nested class can be protected by the outer class from external classes This is a special relationship 4 Nested Classes A nested class produces a separate bytecode file If a nested class called Inside is declared in an outer class called Outside, two bytecode files will be produced: Outside.class Outside$Inside.class 5 Inner classes Nested classes can be declared as static. in that case, they cannot refer to instance variables or methods declared in the class A non-static nested class is called an inner class 6 Abstract Classes // Class Food is an abstract representation of a food item. abstract class Food { // Returns calories of fat for the food item. public abstract double CaloriesOfFat(); } // class Food 7 Class Pepporoni // Class Pepperoni is derived from an abstract class // and implements its method. class Pepperoni extends Food { private double CaloriesOfFat = 100; // Returns the number of fat calories. public double CaloriesOfFat() { return CaloriesOfFat; } // method } // class Pepperoni 8 Dinner class public class Dinner { // Creates a Pepperoni object and invokes its method. public static void main (String[] args) { Pepperoni slice = new Pepperoni(); System.out.println (slice.CaloriesOfFat()); } // method main } // class Dinner 9 Abstract Classes See Printer.java File int NumberOfCharacters Binary_File = .class file Text_File Image_File 10 Interfaces A Java interface is a collection of constants and abstract methods Let’s review an example: 11 Interfaces interface is a reserved word public interface Doable { public abstract void doThis(); public abstract int doThat(); public abstract void doThis2 (float value, char ch); public boolean doTheOther (int num); } A semicolon immediately follows each method header 12 Interfaces public class CanDo implements Doable { public void doThis () { // whatever } public void doThat () { // whatever } implements is a reserved word Each method listed in Doable is given a definition // etc. } 13 interface, Geometry The interface, Geometry, consists of one static constant and two abstract methods. 1. public interface Geometry 2. { 3. public static final double PI = 3.14159; // a constant 4. public abstract double area(); 5. public abstract double perimeter(); 6. } Interfaces Unlike a class: 1. all methods of an interface are abstract, i.e., 2. there are no implementations at all, and 3. an interface has no instance variables. Like an abstract class, an interface cannot be instantiated. In contrast to an abstract class, a class does not extend an interface. Instead, a class implements an interface. Problem Statement: Define Circle, Square, and Triangle classes each of which implements the Geometry interface. Java Solution: The following classes implement Geometry, therefore, each class is required to implement the area() and perimeter() methods. 1. 2. 3. 4. 5. 6. 7. 8. 9. public class Circle implements Geometry { private double radius; Circle public Circle() // constructdor { radius = 0.0; } public Circle (double r) // constructdor 10. 11. 12. 13. 14. 15. 16. 17. { 18. 19. 20. { radius = r; } public double perimeter() // method { return 2*PI*radius; } public double area() // method return PI*radius*radius; }} Class Square 1. public class Square implements Geometry 2. { private double side; 3. 4. public Square() 5. // CONSTRUCTORS { 6. side = 0.0; 7. } 8. public Square (double s) 9. { 10. side = s; 11. } 12. public double perimeter() // METHODS 13. { 14. return 4*side; 15. } 16. public double area() 17. { 18. return side*side; 19. 20. } } CLASS Triangle public class Triangle implements Geometry 1. { 2. // three sides a,b,c 3. private double a,b,c; public Triangle (double a1, 1. double b1, double c1) 2. { 3. a = a1; 4. b = b1; 5. c = c1; 6. } public double perimeter() 16. { 17. return a+b+c; 18. } 19. 20. 21. 22. public double area() { double s =(a+b+c)/2.0; return 23. Math.sqrt(s*(s-a)*(s-b)*(s-c)); 24. } 25. } The Comparable Interface Java also provides a large number of ready-made interfaces. One of the most useful Java-supplied interfaces is the Comparable interface. Comparable is an interface with just one method, compareTo(...): interface Comparable public interface Comparable { public abstract int compareTo(Object o); } compareTo(...) returns an integer and accepts any Object reference as an argument. 22 The Comparable Interface A class that implements the Comparable interface implements compareTo(...) so that a.CompareTo(b) returns a negative integer, if a is “less than” b, a.CompareTo(b) returns 0, if a “equals” b, and a.CompareTo(b) returns a positive integer, if a is “greater than” b. A class that implements Comparable is lets its clients know that its objects can be “compared”. The Comparable Interface Problem statement: Define a Production hierarchy with Film and Play as child classes. Film and Play implement the Comparable interface. A Film class has attributes ( instance variables): title, director, screenwriter, and total box office gross, in millions of dollars adjusted for inflation. The methods of a Film class include: constructors, getters and setters, and a method that displays the values of each attribute. 25 Like a Film class , a Play class has: a title, a director, and a writer or playwright. Additionally, a Play object holds the number of performances of a play. The Play methods are: getter and setter methods, and a method that displays the values of each attribute. 26 A Play class and a Film class - Implement Comparable Interface and extend Productions 27 Inheritance by Factoring The Play class and the Film class are very similar and share many of the same attributes and methods. They both will extend another class Production - it will contain the methods and attributes common to both. This is called “Inheritance by Factoring” 28 Inheritance Hierarchy Play extends Production; Film extends Production They also both implement the Comparable Interface 29 Because Play implements Comparable, Play must implement compareTo(…). public class Play extends Production implements Comparable { // OTHER METHODS public int compareTo(Object p) {// from the Comparable interface if ( ! (p instanceof Play) ) // p must BE A PLAY OBJECT { System.out.println("Error: Object does not belong to Play"); System.exit(0); } // p must be cast to TYPE Play if (performances < ((Play) p).performances) { return -1; if (performances > (( Play )p).performances) return 1; return 0; } } Examine the Code - the instanceOf operator // method defined in the Comparable interface public int compareTo(Object p) // p must BE A PLAY OBJECT if ( ! (p instanceof Play) ) { System.out.println("Error: Object does not belong to Play class"); System.exit(0); // exits the program } 31 Examine Code: Casting Objects // p must be cast to TYPE Play if (performances < { return -1; ((Play) p).performances) // number of performances less than if (performances > (( Play )p).performances) return 1; ; // number of performances greater than // returns they are equal return 0; } } 32 Comparable interface The following compareTo() method is located in a class of type FILM The Film class implements Comparable and extends the Production class 33 COMPARISON OF BOX OFFICE GROSSES FOR THE TWO FILM OBJECTS, returning 0, 1 or -1 public int compareTo(Object p)// “p” should be a Film object { if ( !(p instanceof Film)) { // p must BE A FILM OBJECT System.out.println("Error: object must belong to Film"); System.exit(0); } // Now cast p to a FILM object and compare values if (boxOfficeGross < ((Film) p ).boxOfficeGross ) return -1; if (boxOfficeGross > ((Film)p).boxOfficeGross) return 1; } Interfaces & Constants interface constants require nothing special of the implementing class Constants in an interface can be used in the implementing class as if they were declared locally This feature provides a convenient technique for distributing common constant values among multiple classes eg. The value of pi = 3.14159265 35 Interfaces An interface can extend other interfaces The child interface inherits the constants and abstract methods of the parent A class that implements the child interface must define all methods in both the parent and child 36 Class and Interfaces Hierarchy Note that the interface hierarchy and the class hierarchy are distinct. The interface hierarchy does not define an ISA relationship. It’s ability to speak is a functionality it is given. 37 Interfaces - SUMMARY An interface can be implemented by multiple classes Each implementing class can provide their own unique version of the method definitions An interface is not a class, and cannot be used to instantiate an object of the Interface An interface is not part of the class hierarchy A class can be derived from a base class and implement one or more interfaces 38 Interfaces A class that implements multiple interfaces specifies all of them in its header, separated by commas The ability to implement multiple interfaces provides many of the features of multiple inheritance, the ability to derive one class from two or more parents Java does not support multiple inheritance 39 Some details on when to use and interface or an abstract class: If Abstract class A requires abstract methods should classes B and C extend it or implement it ? Rules: If all the methods in B must be implemented differently from the same methods in C, make A an interface. 40 INTERFACES The methods in A then require that these methods must be implemented in B and C. A can act as the super type, listing the methods that MUST be implemented in B & C. 41 Interfaces - Review Interfaces have the same access levels as classes, public and package. A class can implement more one interface. If a parent class implements an interface, its child classes automatically implements the interface. An interface, like a class, defines a type. 42 Interfaces – Static Fields 1. Fields can be declared in an interface. 2. All fields are public, static and final. (Constants) 3. Declaring a field to be any other access level except public is a compile error. 4. If no access level is given, it defaults to public. 5. If a field is not explicitly declared to be static or final, the field is still static and final. 43 Interfaces - Example interface WithStatic // CONTAINS STATIC CONSTANTS { public static final int EXPLICIT = 42; // VALID public static int IS_FINAL = 12; // VALID public int IS_FINAL_AND_STATIC = 3; // VALID protected int COMPILE_ERROR = 4; public int NO_VALUE_COMPILE_ERROR; } 44 STATIC FIELDS - EXAMPLE class Radio implements WithStatic { public void AM() { System.out.println( IS_FINAL ); } } // close class class Test { public static void main( String args[] ) { System.out.println( WithStatic.EXPLICIT ); // uses interface name System.out.println( Radio.EXPLICIT ); // uses class name Radio megaBass = new Radio(); // create object of class System.out.println( megaBass.EXPLICIT ); // uses object name megaBass.AM(); } } 45 Method Name Conflicts A class implements two interfaces that each have a method with the same name, Square(): If both Square() methods in each interface have different signatures( # and type of parameters), then the class implements two overloaded methods. If both methods have the same signature and the same return type, then the class implements only the one square() method. 46 Method Name Conflicts If both Square() methods have the same signature and different return types, then the class can not implement both interfaces. 47 Conflicting interfaces If both methods have the 1. same signature, 2. same return type but differ in the types of exceptions they throw, then the class implements only the one method, but it must contain the exceptions of both methods. 48 If a class implements two interfaces that each have a field with the same name, say bar, then the class must use the full interface names for the fields. 49 Extending Interfaces One interface can inherit from another interface, supporting multiple inheritance. interface Door { public void open(); public void close(); } interface LockableDoor extends Door { public void lock(); public void unlock(); } 50 Extending Interfaces class CarDoor implements LockableDoor { private boolean isLocked = false; // methods inherited from Interface DOOR public void open() { if ( !isLocked) System.out.println( "Enter the car" ); } public void close() { System.out.println( "Closing the door"); } 51 Extending Interfaces // methods inherited from Lockable door public void lock() { isLocked = true; } public void unlock() { isLocked = false; } } //close class 52 Some issues with extending Interaces public class TestDoor { public static void main( String[] args ) { Door d = new CarDoor(); d.open(); // open() is in Door Interface //Compile error –lock() not in Door Interface d.lock(); // lock is in Lockable interface // must cast d to a lockable door LockableDoor better = (LockableDoor) d; better.lock(); //OK } } 53 Packages A Java package is a collection of classes The classes in a package may or may not be related by inheritance A package is used to group similar and interdependent classes together 54 package The Java API is composed of multiple packages The import statement is used to assert that a particular program will use classes from a particular package 55 Packages A programmer can define a package and add classes to it The package statement is used to specify that all classes defined in a file belong to a particular package The syntax of the package statement is: package package-name; package Graph; e.g. It must be located at the top of a file, and there can be only one package statement per file 56 Packages The classes must be organized in the directory structure such that they can be found when referenced by an import statement The import statement specifies particular classes, or an entire package of classes, that can be used in that program 57 Packages As a rule of thumb, if you will use only one class from a package, import that class specifically imports a single class in the util package import Java.util.Iterator If two or more classes will be used, use the * wildcard character in the import statement to provide access to all classes in the package import java.util.*; // imports all the classes in the package 58