ch6 (7)


developer.com - Reference Click here to support our advertisers SHOPPING JOB BANK CLASSIFIEDS DIRECTORIES REFERENCE Online Library LEARNING CENTER JOURNAL NEWS CENTRAL DOWNLOADS COMMUNITY CALENDAR ABOUT US Journal: Get the weekly email highlights from the most popular journal for developers! Current issue developer.com developerdirect.com htmlgoodies.com javagoodies.com jars.com intranetjournal.com javascripts.com All Categories : Java Chapter 6 Interfaces CONTENTS The Purpose of Java Interfaces The Benefits of Interfaces Declaring Interfaces Implementing Interfaces The CDrawApp Interface Example The CGTextEdit Interface Updating the CGText Class The CGTextPoint Class The CGTextBox Class Updating the CDraw Class Running the Example Example Summary Using Interfaces as Abstract Types Interface Constants Extending Interfaces Combining Interfaces Summary In this chapter you'll learn how to use Java interfaces to provide a common set of methods by which a group of classes can be accessed and to implement features of multiple inheritance. You'll cover the use of interface constants and learn how to declare objects using interface types. You will also learn how to extend and combine interfaces. When you finish this chapter, you'll be able to use interfaces with your Java classes. The Purpose of Java Interfaces The Java interface construct is borrowed from the Objective-C protocol. It is used to identify a common set of methods for the group of classes that implement the interface. It is also used to share constants between classes. Interfaces are used to provide the benefits of multiple inheritance without its implementation difficulties. They allow several classes to share a standard set of methods and constants without requiring these methods and constants to be implemented by a common superclass. Interfaces provide a standard framework for accessing classes. They are analogous to the interfaces that we encounter in everyday life. Any large class of real-world objects that you regularly manipulate usually has a standard interface. Radios and televisions provide a common set of controls for tuning channels and adjusting audio volume. Cars come with a standard interface for steering, throttling, and braking. Automated bank tellers provide the same general interface for performing bank transactions. To realize the potential use of Java interfaces, consider the diversity of objects that are manipulated by GUI-building programs. Such programs provide the capability to generate graphical user interfaces by clicking on interface controls and dragging them to appropriate places on the windows and dialog boxes being developed. The objects implementing these controls may support many different sets of methods. For example, one subset of the controls may be required to support cut, copy, and paste operations. These methods might be grouped into an EditObject interface. Another subset of the interface controls may be required to support click and double-click operations. These objects might implement a Clickable interface. Another subset may support drag-and-drop operations and implement the Draggable interface. Other groups of objects may implement multiple interfaces. For example, there might be objects that are both Clickable and Draggable. The Benefits of Interfaces Interfaces provide many advantages to the Java programmer. One is that they allow standard sets of methods to be used across the class hierarchy. For example, you can define the Editable interface to support cut, copy, and paste operations. The Editable interface can then be implemented by relevant classes and establish a uniform approach to implementing these common operations. Interface types allow objects to be referenced by the methods they support without considering their location in the class hierarchy. They make maximal use of dynamic binding, allowing objects to be accessed independently of their implementation details. For example, parameters can be defined as interface types and used by methods. These methods can invoke the interface methods of their arguments without having to determine the classes to which the arguments belong. Interfaces also support selective multiple inheritance. They allow various subsets of the features supported by different classes to be shared without mandating that all features of these classes be uniformly imposed as the result of inheritance. Finally, because interfaces are declared independently of classes, they are unaffected by changes to specific classes or to the class hierarchy as a whole. Declaring Interfaces Interfaces, like classes, are not objects, but type definitions that can be used to declare an object. Interfaces are declared as follows: InterfaceModifiers interface InterfaceName ExtendsClause InterfaceBody The allowed interface modifiers are abstract and public. By default, all interfaces are abstract. The public access specifier allows interfaces to be accessed outside of the package in which they are declared, in the same manner as with classes. Only one class or interface may be declared public in a given compilation unit. The compilation unit must have the same name as its public interface or class. The extends clause is similar to the class extends clause and is covered later in this chapter. The body of an interface begins with an opening brace ({), consists of zero or more variable or method declarations, and ends with a closing brace (}). All variables declared in an interface body are assumed to be both static and final, must have a constant initializer, and are implemented as constant class variables. All methods declared in an interface body are assumed to be abstract and do not have method bodies. Only access methods can be declared within an interface; constructors are not allowed. The access specifier of a method is that of the interface in which it is declared. An example of a simple interface declaration is as follows: public interface Clickable {  void click();  void doubleClick(); } This Clickable interface is declared as public so that it can be accessed outside its package. It contains two method declarations, click() and doubleClick(). These methods must be supported by all classes that implement the Clickable interface. Implementing Interfaces The interfaces implemented by a class are identified in the implements clause of the class declaration. For example, the following class implements the Scrollable and Clickable interfaces: class ExampleClass implements Scrollable, Clickable { } A non-abstract class must implement all interface methods that are not implemented by its superclasses. abstract classes are not required to implement interface methods. They can defer interface implementation to their non-abstract subclasses. The CDrawApp Interface Example To provide a concrete example of the use of interfaces, we'll extend the CDrawApp program, introduced in Chapter 5, "Classes and Objects," to include support for editable objects. Editable objects are objects that display text on the grid and can be edited using the CGTextEdit interface. The CGText class will be modified to support this interface. The CGPoint and CGBox classes will be extended by the subclasses, CGTextPoint and CGTextBox, both of which provide the capability to display text on the grid. The CGText, CGTextPoint, and CGTextBox classes will implement the CGTextEdit interface. Figure 6.1 shows the extensions to the Chapter 5 class hierarchy that were made to support this example. Figure 6.1 : Extensions to the CDrawApp class hierarchy. Before going on to edit and compile the source code files for this example, be sure to create a ch06 subdirectory under c:\java\jdg. This subdirectory should be used to store all the source Java files that you develop in this chapter. The CGTextEdit Interface The CGTextEdit interface is quite simple. Its source code is shown in Listing 6.1. Listing 6.1. The CGTextEdit interface source code. package jdg.ch06; public interface CGTextEdit {  public void replaceText(String s);  public void upperCase();  public void lowerCase(); } The CGTextEdit interface source code declares three methods: replaceText(), upperCase(), and lowerCase(). These methods must be provided by all classes that implement the CGTextEdit interface. The replaceString() method is used to replace the text associated with an object with the text contained in the String's parameter. The upperCase() and lowerCase() methods are used to convert the text associated with an object to upper- and lowercase, respectively. CGTextEdit and all its interfaces are declared as public, allowing them to be accessed outside of the jdg.ch06 package. The public modifiers used with the method declarations are redundant. Any method declared in a public interface is public, by default. After you have entered the CGTextEdit interface into the file, CGTextEdit.java, use javac to compile CGTextEdit.java. Do this from within the ch06 directory. Updating the CGText Class The CGText class, developed in Chapter 5, will be updated to implement the CGTextEdit interface. The easiest way to do this is to copy CGText.java from the c:\java\jdg\ch05 directory to the c:\java\jdg\ch06 directory and then edit it. Its source code is shown in Listing 6.2. Listing 6.2. The CGText class source code. package jdg.ch06; import jdg.ch05.CGObject; import jdg.ch05.Point; import jdg.ch05.PrintCGrid; import java.lang.System; // CGText.java public class CGText extends CGObject implements CGTextEdit {  // Variable declarations  String text;  // Method declarations  public CGText(Point p,String s) {   location = p;   drawCharacter = ' ';   text = s;  }  public void display(PrintCGrid grid) {   Point p = new Point(location);   for(int i=0;i<text.length();++i){    grid.putCharAt(text.charAt(i),p);    p = p.add(1,0);   }  }  public void describe() {   System.out.println("CGText "+location.toString()+" "+text);  }  public void replaceText(String s) {   text=s;  }  public void upperCase() {   text = text.toUpperCase();  }  public void lowerCase() {   text = text.toLowerCase();  } } All you need to do is to change the package statement, add the import statements, edit the class declaration, and add the last three methods that implement the CGTextEdit interface. Because this class is contained in the jdg.ch06 package, you need to import the CGObject, Point, and PrintCGrid classes from the jdg.ch05 package. The class declaration is changed to add the implements clause with the CGTextEdit interface. The three new methods are all very simple. The replaceText() method assigns text to the new value passed by the s parameter. The upperCase() and lowerCase() methods use the toUpperCase() and toLowerCase() methods of the String class to perform their conversions. You should compile the new CGText.java before moving on to the next class. The CGTextPoint Class The CGTextPoint class extends the CGPoint class to add the capability to display text along with the character point. (See Listing 6.3.) Listing 6.3. The CGTextPoint class source code. package jdg.ch06; import jdg.ch05.Point; import jdg.ch05.CGPoint; import jdg.ch05.PrintCGrid; import java.lang.System; // CGTextPoint.java public class CGTextPoint extends CGPoint implements CGTextEdit {  // Variable declarations  String text;  // Method declarations  public CGTextPoint(Point p,char ch,String s) {   super(p,ch);   text = s;  }  public CGTextPoint(Point p,String s) {   super(p);   text = s;  }  public CGTextPoint(Point p,char ch) {   super(p,ch);   text = "";  }  public CGTextPoint(Point p) {   super(p);   text = "";  }  public void display(PrintCGrid grid) {   super.display(grid);   Point p = location.add(1,0);   for(int i=0;i<text.length();++i){    grid.putCharAt(text.charAt(i),p);    p = p.add(1,0);   }  }  public void describe() {   System.out.print("CGTextPoint "+String.valueOf(drawCharacter)+" ");   System.out.println(location.toString()+" "+text);  }  public void replaceText(String s) {   text=s;  }  public void upperCase() {   text = text.toUpperCase();  }  public void lowerCase() {   text = text.toLowerCase();  } } CGTextPoint declares the variable text. This variable is used to store the text associated with the point. It provides four constructors, each of which uses the super() constructor call statement to invoke the constructors of the CGPoint class. The four constructors allow CGTextPoint to be constructed using different combinations of parameters. The display() method invokes the display() method of its superclass to display the point at its location on the grid. It then displays the value of the text variable to the immediate right of this point. The describe() method displays a description of the text point on the console window. The replaceText(), upperCase(), and lowerCase() methods are the same as those of the new CGText class. The CGTextBox Class The CGTextBox class extends the CGBox class to add the capability to display text within a box. (See Listing 6.4.) The size of the box is automatically fitted to the size of the text to be displayed. Listing 6.4. The CGTextBox class source code. package jdg.ch06; import jdg.ch05.Point; import jdg.ch05.CGBox; import jdg.ch05.PrintCGrid; import java.lang.System; // CGTextBox.java public class CGTextBox extends CGBox implements CGTextEdit {  // Variable declarations  String text;  // Method declarations  public CGTextBox(Point ulCorner, char ch, String s) {   super(ulCorner,ulCorner.add(s.length()+1,2),ch);   text = s;  }  public CGTextBox(Point ulCorner, String s) {   super(ulCorner,ulCorner.add(s.length()+1,2));   text = s;  }  public void display(PrintCGrid grid) {   super.display(grid);   Point p = location.add(1,1);   for(int i=0;i<text.length();++i){    grid.putCharAt(text.charAt(i),p);    p = p.add(1,0);   }  }  public void describe() {   System.out.print("CGTextBox "+String.valueOf(drawCharacter)+" ");   System.out.println(location.toString()+" "+lr.toString()+" "+text);  }  public void replaceText(String s) {   text=s;   lr=location.add(text.length()+1,2);  }  public void upperCase() {   text = text.toUpperCase();  }  public void lowerCase() {   text = text.toLowerCase();  } } The CGTextBox class source code defines the text variable in the same manner as the CGTextPoint class and provides two constructors for initializing objects of its class. Both constructors use calls to the CGBox class to support the initialization. The parameters to these calls calculate the lower-right corner of the box using the upper-left corner as a reference point and adding horizontal and vertical offsets that size the box based on the length of the text it contains. The display() method displays a box using the display() method of its parent. It then displays text within the box. The describe() method prints a box's parameters on the console window. The upperCase() and lowerCase() methods are the same as those of the CGTextPoint class, but the replaceText() method is different. It updates the lr variable to correctly resize the box based on changes to the length of the text variable. Updating the CDraw Class The CDraw class is updated to support the Edit Text command. This requires changes to all its access methods except the addText() method. The source code of the CDrawApp and CDraw classes is shown in Listing 6.5. Listing 6.5. The CDrawApp and CDraw classes. package jdg.ch06; import jdg.ch05.Point; import jdg.ch05.CGrid; import jdg.ch05.PrintCGrid; import jdg.ch05.BorderedPrintCGrid; import jdg.ch05.CGObject; import jdg.ch05.CGPoint; import jdg.ch05.CGBox; import jdg.ch05.KeyboardInput; import java.lang.System; import java.lang.ClassCastException; import java.io.IOException; class CDrawApp {  public static void main(String args[]) throws IOException {   CDraw program = new CDraw();   program.run();  } } class CDraw {  // Variable declarations  static KeyboardInput kbd = new KeyboardInput(System.in);  BorderedPrintCGrid grid;  // Method declarations  CDraw() {   grid = new BorderedPrintCGrid();  }  void run() throws IOException {   boolean finished = false;   do {    char command = getCommand();    switch(command){     case 'P':      addPoint();      System.out.println();      break;     case 'B':      addBox();      System.out.println();      break;     case 'T':      addText();      System.out.println();      break;     case 'U':      grid.deleteLastObject();      System.out.println();      break;     case 'C':      grid.clearGrid();      System.out.println();      break;     case 'S':      grid.show();      break;    case 'E':     editText();     break;    case 'X':     finished = true;     default:      System.out.println();    }   } while (!finished);  }  char getCommand() throws IOException {   System.out.print("CDrawApp P - Add a Point U - Undo Last Add");   System.out.println(" E - Edit Text");   System.out.print("Main Menu B - Add a Box C - Clear Grid");   System.out.println(" X - Exit CDrawApp");   System.out.print(" T - Add Text S - Show Grid");   System.out.print(" Enter command: ");   System.out.flush();   return Character.toUpperCase(kbd.getChar());  }  void addPoint() throws IOException {   System.out.println("Add Point Menu");   System.out.println(" Location:");   Point p = kbd.getPoint();   System.out.print(" Character: ");   System.out.flush();   char ch = kbd.getChar();   if(ch==' ') ch = '+';   System.out.print(" Add text (y/n): ");   System.out.flush();   if('Y'==Character.toUpperCase(kbd.getChar())) {    System.out.print(" Text: ");    System.out.flush();    String s = kbd.getText();    CGTextPoint cgtp = new CGTextPoint(p,ch,s);    cgtp.addToGrid(grid);   }else{    CGPoint cgp = new CGPoint(p,ch);    cgp.addToGrid(grid);   }  }  void addBox() throws IOException {   System.out.println("Add Box Menu");   System.out.println(" Upper Left Corner:");   Point ul = kbd.getPoint();   System.out.print(" Add text (y/n): ");   System.out.flush();   if('Y'==Character.toUpperCase(kbd.getChar())) {    System.out.print(" Text: ");    System.out.flush();    String s = kbd.getText();    System.out.print(" Character: ");    System.out.flush();    char ch = kbd.getChar();    if(ch==' ') ch = '#';    CGTextBox cgtb = new CGTextBox(ul,ch,s);    cgtb.addToGrid(grid);   }else{    System.out.println(" Lower Right Corner:");    Point lr = kbd.getPoint();    System.out.print(" Character: ");    System.out.flush();    char ch = kbd.getChar();    if(ch==' ') ch = '#';    CGBox box = new CGBox(ul,lr,ch);    box.addToGrid(grid);   }  }  void addText() throws IOException {   System.out.println("Add Text Menu");   System.out.println(" Location:");   Point p = kbd.getPoint();   System.out.print(" Text: ");   System.out.flush();   String text = kbd.getText();   CGText cgt = new CGText(p,text);   cgt.addToGrid(grid);  }  void editText() throws IOException {   System.out.println("Current Objects:");   int numObjects = grid.getNumObjects();   for(int i=0;i<numObjects;++i){    System.out.print(" "+String.valueOf(i)+" ");    grid.getObject(i).describe();   }   if(numObjects > 0){    System.out.print("Select an object to edit: ");    System.out.flush();    int objIndex = kbd.getInt();    CGObject obj = grid.getObject(objIndex);    try {     editText((CGTextEdit) obj);    }catch (ClassCastException ex){     System.out.println("Object is not editable.");    }   }else System.out.println("(none)");   System.out.println();  }  void editText(CGTextEdit obj) throws IOException {   System.out.println("Text Edit Menu");   System.out.println(" R - Replace Text");   System.out.println(" L - Lower Case");   System.out.println(" U - Upper Case");   System.out.print("Enter command: ");   System.out.flush();   char ch = kbd.getChar();   ch = Character.toUpperCase(ch);   switch(ch) {    case 'R':     System.out.print("Enter new text: ");     System.out.flush();     String s = kbd.getText();     obj.replaceText(s);     break;    case 'L':     obj.lowerCase();     break;    case 'U':     obj.upperCase();     break;   }  } } The run(), getCommand(), addPoint(), and addBox() methods are updated to support the Edit Text command. The two overloaded editText() methods are added to process this command. The switch statement of the run() method adds the 'E' case to its list of command options, calling the editText() method to process the Edit Text command. The getCommand() method adds the Edit Text command to its menu display. The addPoint() and addBox() methods query the user to determine whether text should be added to the point or box. If the user declines to add text, a CGPoint or CGBox object is created and added to the grid. If the user indicates that he or she wants to add text to the point or box, the user is prompted to enter the text. In this case, CGTextPoint and CGTextBox objects are created and added to the grid. The two editText() methods share the same name but provide completely different processing. The first editText() method is invoked when the user enters the Edit Text command. It displays a list of the objects that are currently added to the grid. It does this by using the getNumObjects() method of the PrintCGrid class to find out how many objects there are and then retrieving those objects using the getObject() method of the PrintCGrid class. The following line of code concatenates two method invocations: grid.getObject(i).describe(); It retrieves an object of class CGObject by invoking the getObject() method of the PrintCGrid class. It then invokes the object's describe() method so that it will display its description on the console window. If there are no objects currently added to the grid, the editText() method indicates this fact by displaying (none) to the console window. Otherwise, the user is prompted to enter the number of the object to edit. This number is the number listed in the current object display. The number entered by the user is used to retrieve the object to be edited using the getObject() method. After the object is retrieved, the editText() method tries to edit the text associated with the object by invoking the second editText() method. If the object does not implement the CGTextEdit interface, a ClassCastException is thrown during the invocation of the second editText() method. The first editText() method catches this exception and reports the selected object as not being editable. The second editText() method displays a Text Edit Menu prompt to the user and invokes the replaceText(), lowerCase(), and upperCase() methods to process the commands entered by the user. Running the Example The CDrawApp program is compiled and executed in the same manner as its Chapter 5 predecessor. You should notice the additional Edit Text command provided in the CDrawApp main menu: C:\java\jdg\ch06>java jdg.ch06.CDrawApp CDrawApp    P - Add a Point   U - Undo Last Add   E - Edit Text Main Menu   B - Add a Box     C - Clear Grid      X - Exit CDrawApp             T - Add Text      S - Show Grid       Enter command: We'll add a few objects to the grid, display them, and then edit their text. After you learn how to use the new program, we'll discuss its features as they relate to interfaces. Enter P to add a point to the grid. Set its x-coordinate to 60, its y-coordinate to 10, and its draw character to @: Add Point Menu  Location:   x-coordinate: 60   y-coordinate: 10  Character: @  Add text (y/n): You are asked whether you want to add text to the point. Press Y to add text. You are then prompted to add your text. Enter at sign as your text, as shown in the following display output: Add Point Menu  Location:   x-coordinate: 60   y-coordinate: 10  Character: @  Add text (y/n): y   Text: at sign The CDrawApp main menu is then redisplayed. Enter B to add a box. Set the box's upper-left corner as follows: Add Box Menu  Upper Left Corner:   x-coordinate: 4   y-coordinate: 4  Add text (y/n): Enter Y to add text to the box. You are prompted to enter your text. Enter the text Java's interfaces support multiple inheritance.. Then set the box's draw character to +. Your display output should look like the following: Add Box Menu  Upper Left Corner:   x-coordinate: 4   y-coordinate: 4  Add text (y/n): y   Text: Java's interfaces support multiple inheritance.  Character: + Enter B to enter another box. This box will not contain any text. Enter the coordinates for the box's corners, as follows: Add Box Menu  Upper Left Corner:   x-coordinate: 65   y-coordinate: 15  Add text (y/n): n  Lower Right Corner:   x-coordinate: 72   y-coordinate: 18 Then set its draw character to a hyphen: Character: - You should have noticed that when a box contains text, its lower-right corner is not specified. That's because the program computes it based on the length of the text to be displayed with the box. You're almost done adding objects to the grid. Enter T to add text to the grid. Set the text's location and value as follows: Add Text Menu  Location:   x-coordinate: 1   y-coordinate: 18  Text: UPPER CASE Or lower case You now have enough objects to work with. Enter S to display the grid. It should look like this: *************************************************************************** *                                                                           * *                                                                           * *                                                                           * *                                                                           * *    +++++++++++++++++++++++++++++++++++++++++++++++++                      * *    +Java's interfaces support multiple inheritance.+                      * *    +++++++++++++++++++++++++++++++++++++++++++++++++                      * *                                                                           * *                                                                           * *                                                                           * *                                                            @ at sign      * *                                                                           * *                                                                           * *                                                                           * *                                                                           * *                                                                 --------  * *                                                                 -      -  * *                                                                 -      -  * * UPPER CASE Or lower case                                        --------  * *                                                                           * *************************************************************************** Let's start editing these objects. Enter E to select an object to edit: CDrawApp    P - Add a Point   U - Undo Last Add   E - Edit Text Main Menu   B - Add a Box     C - Clear Grid      X - Exit CDrawApp             T - Add Text      S - Show Grid       Enter command: e Current Objects:  0 CGTextPoint @ (60,10) at sign  1 CGTextBox + (4,4) (52,6) Java's interfaces support multiple inheritance.  2 CGBox - (65,15) (72,18)  3 CGText (1,18) UPPER CASE Or lower case Select an object to edit: A list of the grid's current objects is displayed. Enter 2 to select the object of class CGBox. Because this object does not implement the CGTextEdit interface, it is identified as not being editable, as shown in the following console output: Object is not editable. See if you can find where this processing was performed within the CDraw class. Enter E again to edit another object. The list of current objects is again displayed. Enter 1 to select the object of class CGTextBox. The Text Edit Menu prompt is displayed as follows: Text Edit Menu  R - Replace Text  L - Lower Case  U - Upper Case Enter command: This menu allows you to use the methods of the CGTextEdit interface to edit the objects that implement the interface. Enter R to replace the text associated with the CGTextBox object. You are then prompted to enter the new text for this object. Enter interfaces to complete the editing. Your display should contain the following output: Enter command: r Enter new text: interfaces Enter S to see how the grid was updated. Notice how the size of the CGTextBox was changed to fit the size of the text it contains: ++++++++++++ +interfaces+ ++++++++++++ Enter E and then 0 to edit the object of class CGTextPoint. Then type U to change it to uppercase. Use the show command to verify that the text has been changed to uppercase. Enter E, 3, and L in succession to change the case of the text contained in the CGText object. Use the Show Grid command to redisplay the grid: *************************************************************************** *                                                                           * *                                                                           * *                                                                           * *                                                                           * *    ++++++++++++                                                           * *    +interfaces+                                                           * *    ++++++++++++                                                           * *                                                                           * *                                                                           * *                                                                           * *                                                            @ AT SIGN      * *                                                                           * *                                                                           * *                                                                           * *                                                                           * *                                                                 --------  * *                                                                 -      -  * *                                                                 -      -  * * upper case or lower case                                        --------  * *                                                                           * *************************************************************************** Now type X to exit the CDrawApp program. Example Summary The CDrawApp program illustrates the use of a simple interface. The CGTextEdit interface, used in this example, provides a common set of access methods to three classes on different branches of the CDrawApp class hierarchy, as shown in Figure 6.2. Figure 6.2 : The

Wyszukiwarka

Podobne podstrony:
ch6 (11)
CH6
ch6 (5)
CH6
ch6 (10)
Beginning smartphone?velopment CH6
CH6 (3)
ch6 (8)
Cisco2 ch6 Focus
ch6 (14)
ch6 (9)
ch6
Cisco2 ch6 Vocab
0472113038 ch6
ch6 (12)
ch6 (4)

więcej podobnych podstron