330 likes | 490 Views
Chapter 10. Object-Oriented Programming Part 3C: Interfaces. Interfaces. A class can inherit directly from only one class , that is, a class can extend only one class. To allow a class to inherit behavior from multiple sources, Java provides the interface .
E N D
Chapter 10 Object-Oriented Programming Part 3C: Interfaces
Interfaces A class can inherit directly from only one class, that is, a class can extend only one class. To allow a class to inherit behavior from multiple sources, Java provides theinterface. • An interface typically specifies behavior that a class will implement. Interface members can be any of the following: · classes · constants ·abstract methods · other interfaces
Interface Syntax To define an interface, use the following syntax: accessModifier interface InterfaceName { // body of interface } All interfaces are abstract; thus, they cannot be instantiated. The abstract keyword, however, can be omitted in the interface definition.
interfaceis a reserved word A semicolon immediately follows each method header Interfaces None of the methods in an interface are given a definition (body) public interface Doable { public void doThis(); public intdoThat(); public void doThis2 (float value, char ch); public booleandoTheOther (int num); }
Finer Points of Interfaces • An interface's fields are public, static, and final. These keywords can be specified or omitted. • When you define a field in an interface, you must assign a value to the field. • All methods within an interface must be abstract, so the method definition must consist of only a method header and a semicolon. The abstract keyword also can be omitted from the method definition.
Interfaces • An interface cannot be instantiated • Methods in an interface have public visibility by default • A class formally implements an interface by: • stating so in the class header • providing implementations for each abstract method in the interface • If a class asserts that it implements an interface, it must define all methods in the interface
implementsis a reserved word Each method listed inDoableis given a definition Interfaces public class CanDo implements Doable { public void doThis () { // whatever } public void doThat () { // whatever } // etc. }
Polymorphism via Interfaces • An interface name can be used as the type of an object reference variable Speaker current; • The current reference can be used to point to any object of any class that implements the Speaker interface • The version of speak that the following line invokes depends on the type of object that current is referencing current.speak();
Polymorphism via Interfaces • Suppose two classes, Philosopher and Dog, both implement the Speaker interface, providing distinct versions of the speak method • In the following code, the first call to speak invokes one version and the second invokes another: Speaker guest = new Philospher(); guest.speak(); guest = new Dog(); guest.speak();
Interfaces • The Java standard class library contains many helpful interfaces • The Comparable interface contains one abstract method called compareTo, which is used to compare two objects • We know about the compareTo method of the String class • The String class implements Comparable, giving us the ability to put strings in lexicographic order
The Comparable Interface • Any class can implement Comparable to provide a mechanism for comparing objects of that type if (obj1.compareTo(obj2) < 0) System.out.println ("obj1 is less than obj2"); • The value returned from compareTo should be negative is obj1 is less that obj2, 0 if they are equal, and positive if obj1 is greater than obj2 • When a programmer designs a class that implements the Comparable interface, it should follow this intent
The Comparable Interface • It's up to the programmer to determine what makes one object less than another • For example, you may define the compareTo method of an Employee class to order employees by name (alphabetically) or by employee number • The implementation of the method can be as straightforward or as complex as needed for the situation
The Iterator Interface • An iterator is an object that provides a means of processing a collection of objects one at a time • An iterator is created formally by implementing the Iterator interface, which contains three methods • The hasNext method returns a boolean result – true if there are items left to process • The next method returns the next object in the iteration • The remove method removes the object most recently returned by the next method
The Iterator Interface • By implementing the Iterator interface, a class formally establishes that objects of that type are iterators • The programmer must decide how best to implement the iterator functions • Once established, the for-each version of the for loop can be used to process the items in the iterator
Interfaces • You could write a class that implements certain methods (such as compareTo) without formally implementing the interface (Comparable) • However, formally establishing the relationship between a class and an interface allows Java to deal with an object in certain ways • Interfaces are a key aspect of object-oriented design in Java
Inheriting from an Interface To inherit from an interface, a class declares that it implements the interface in the class definition, using the following syntax: accessModifier class ClassName extends SuperclassName implements Interface1, Interface2, … • The extends clause is optional. • A class can implement 0, 1, or more interfaces. • When a class implements an interface, the class must provide an implementation for each method in the interface.
Interface Hierarchies • Inheritance can be applied to interfaces as well as classes • That is, one interface can be derived from another interface • The child interface inherits all abstract methods of the parent • A class implementing the child interface must define all methods from both the ancestor and child interfaces • Note that class hierarchies and interface hierarchies are distinct (they do not overlap)
Example • Define an abstract class Animal with one abstract method (See Example 10.22): public abstract void draw( Graphics g ); • Define a Moveable interface with one abstract method: public interface Moveable { int FAST = 5; // static constant int SLOW = 1; // static constant void move( ); // abstract method }
Derived Classes • TortoiseRacer class • extends Animal class • implements Moveable interface • implements draw and move methods • TortoiseNonRacer class • extends Animal class • (does not implement Moveable interface) • implements draw method only
Example 10.21 import java.awt.Graphics; public abstract class Animal { private int x; // x position private int y; // y position private String ID; // animal ID /** default constructor Sets ID to blank */ public Animal( ) { ID = ""; } /** Constructor @param rID Animal ID * @param rX x position @param rY y position */ public Animal( String rID, int rX, int rY ) { ID = rID; x = rX; y = rY; }
/** accessor for ID @return ID */ public String getID( ) { return ID; } /** accessor for x @return x coordinate */ public int getX( ) { return x; } /** accessor for y @return y coordinate */ public int getY( ) { return y; } /** mutator for x * @param newX new value for x position */ public void setX( int newX ) { x = newX; }
/** mutator for y * @param newY new value for y position */ public void setY( int newY ) { y = newY; } /** abstract method for drawing Animal * @param g Graphics context */ public abstract void draw( Graphics g ); }
Example 10.22 public interface Moveable { int FAST = 5; // static constant int SLOW = 1; // static constant void move( ); // abstract method }
Example 10.23 import java.awt.Graphics; import java.awt.Color; public class TortoiseRacer extends Animal implements Moveable { /** Default Constructor: calls Animal default constructor */ public TortoiseRacer( ) { super( ); } /** Constructor * @param rID racer Id, passed to Animal constructor * @param rX x position, passed to Animal constructor * @param rY y position, passed to Animal constructor */ public TortoiseRacer( String rID, int rX, int rY ) { super( rID, rX, rY ); }
/** draw: draws the Tortoise at current (x, y) coordinate * implements abstract method in Animal class * @param g Graphics context */ public void draw( Graphics g ) { int startX = getX( ); int startY = getY( ); g.setColor( new Color( 34, 139, 34 ) ); // dark green //body g.fillOval( startX, startY, 25, 15 ); //head g.fillOval( startX + 20, startY + 5, 15, 10 ); //flatten bottom g.clearRect( startX, startY + 11, 35, 4 ); //feet g.setColor( new Color( 34, 139, 34 ) ); // brown g.fillOval( startX + 3, startY + 10, 5, 5 ); g.fillOval( startX + 17, startY + 10, 5, 5 ); }
/** implements move method in Moveable interface * move: calculates the new x value for the racer * Tortoise move characteristics: * "slow & steady wins the race" * increment x by SLOW (inherited from Moveable * interface) */ public void move( ) { setX( getX( ) + SLOW ); } }
Example 10.24 import javax.swing.*; import java.awt.*; public class TortoiseRacerClient extends JApplet { private TortoiseRacer t; public void init( ) { t = new TortoiseRacer( "Tortoise", 50, 50 ); } public void paint( Graphics g ) { for ( int i = 0; i < getWidth( ); i++ ) { t.move( ); t.draw( g ); Pause.wait( .03 ); g.clearRect( 0, 0, getWidth( ), getHeight( ) ); } } }
Designing for Inheritance • As we've discussed, taking the time to create a good software design reaps long-term benefits • Inheritance issues are an important part of an object-oriented design • Properly designed inheritance relationships can contribute greatly to the elegance, maintainabilty, and reuse of the software • Let's summarize some of the issues regarding inheritance that relate to a good software design
Inheritance Design Issues • Every derivation should be an is-a relationship • Think about the potential future of a class hierarchy, and design classes to be reusable and flexible • Find common characteristics of classes and push them as high in the class hierarchy as appropriate • Override methods as appropriate to tailor or change the functionality of a child • Add new variables to children, but don't redefine (shadow) inherited variables
Inheritance Design Issues • Allow each class to manage its own data; use the super reference to invoke the parent's constructor to set up its data • Even if there are no current uses for them, override general methods such as toString and equals with appropriate definitions • Use abstract classes to represent general concepts that lower classes have in common • Use visibility modifiers carefully to provide needed access without violating encapsulation
Restricting Inheritance • The final modifier can be used to curtail inheritance • If the final modifier is applied to a method, then that method cannot be overridden in any descendent classes • If the final modifier is applied to an entire class, then that class cannot be used to derive any children at all • Thus, an abstract class cannot be declared as final • These are key design decisions, establishing that a method or class should be used as is
StaffMember Volunteer Employee Executive Hourly Polymorphism via Inheritance • Consider the following class hierarchy:
Employee Example Cont. • What method(s) would be declared at the Employee level? • What class(es) would override the method? • Any abstract methods?