Defining an Interface

   

You define an interface using syntax very similar to that of a class definition. However, there are a few exceptions. Namely, an interface cannot define any implementation for its methods and its fields are always public, static, and final.

An example interface is shown in Listing 9.2. It is followed by a set of classes declared to implement the interface in Listing 9.3 through Listing 9.5.

Listing 9.2 Sellable.java ” Sellable Product Interface
 public interface Sellable {   String getDescription();   String getUnits();   double getPricePerUnit();   double getWeight(); } 
Listing 9.3 JavaBook.java ” Programming Language Book Class
 public class JavaBook implements Sellable {   public String getDescription() {     return "Java Book";   }   public String getUnits() {     return "Each";   }   public double getPricePerUnit() {     return 39.95;   }   public double getWeight() {     return 4.5;   } } 
Listing 9.4 AbstractAircraft.java ” Abstract Superclass for an Aircraft Product
 public abstract class AbstractAircraft {   protected long weight;   protected int wingspan;   protected String manufacturer;   protected String model;   public abstract float computeFuelRequirement(     float cargoWeight, int numPassengers); } 
Listing 9.5 Boeing767.java ” A Specific Aircraft Product
 public class Boeing767 extends AbstractAircraft implements Sellable {   public Boeing767() {     manufacturer = "Boeing";     model = "767-300";     weight = 395000;     wingspan = 156;   }   public float computeFuelRequirement(float cargoWeight,     int numPassengers) {      // implementation for this specific aircraft would know how to      // compute its fuel requirements, let's just use a constant      return 24000;   }   public String getDescription() {     return manufacturer + " " + model;   };   public String getUnits() {     return "Each";   }   public double getPricePerUnit() {     return 100000000.00;   }   public double getWeight() {     return weight;   } } 

In the preceding listings, Sellable is an interface that defines a set of basic methods needed by an application that displays a description and price for any product offered for sale. The application does not care about any product details other than those referenced in the interface. JavaBook implements Sellable to describe a programming language book that can be sold. Boeing767 is a concrete implementation of AbstractAircraft that also implements Sellable. The value of interfaces can be seen even in this simple, and somewhat contrived, example. A book and a commercial airliner have nothing in common. The fact that they can both be described by a string and sold is not enough to justify deriving them from a common superclass. By instead using an interface, their common behavior relative to product sales can be captured without affecting the class hierarchy.

The Declaration

Interface declarations take the general form

  public  interface NameOfInterface  extends InterfaceList  

where everything in italics is optional.

Public Interfaces

Just like classes, interfaces are defined within a package. If you declare an interface in a source file without a package statement, the compiler places it in the default package just as it would a class. The benefits of namespace management discussed in Chapter 7, "Classes," apply equally to interfaces, so you should avoid leaving your interfaces in the default package.

The optional public modifier in an interface declaration allows classes outside an interface's package to implement it and use it in variable and method declarations. If you omit the modifier, only classes within the same package can use the interface. You will usually declare your interfaces as public.

Interface Name

The rules for an interface name are identical to those for classes. The only requirements on the name are that it begin with a letter, an underscore character, or a currency symbol; contain only these characters and digits; and not be the same as any Java keyword (such as extends or int ). Again, like classes, it is accepted practice to capitalize the first letter of an interface name and use mixed case to separate words rather then underscores.

Note

Just like public classes, public interfaces must be defined in a file named NameOfInterface.java. Although not required for non-public interfaces, it is a good practice to use this same naming convention for those also. This enables both you and the Java compiler to quickly find the source code for your interfaces.


Extending Other Interfaces

If an interface inherits from one or more other interfaces, its declaration identifies each super-interface using the extends keyword. This sub-interface inherits all the methods and fields of its super-interfaces, just as subclasses inherit the fields and methods of their superclasses. When extending more than one interface, separate them in the extends clause using commas.

You extend an interface for purposes similar to those for extending a class, but the implications are quite different. With the exception of purely abstract classes, you can take advantage of previously defined behavior when you extend a class. This reuse of method implementations is one of the strengths of inheritance. However, interfaces have no method bodies, so there can be no reuse of implementation when you extend them. What do you gain from extending an interface then? Declaring an interface is all about specifying a contract for a set of behavior on which other classes in your system can rely. In the previous example, a Sellable interface was defined to use in a sales application. You might find a need in the same program or another to treat Sellable products that exhibit some other unrelated behavior differently. Rather than duplicate the behavior defined by Sellable in another interface that includes the new requirements, you can extend Sellable to create a new contract that reuses the original interface through inheritance.

Note

Interfaces cannot extend classes even though the same extends keyword is used in their declaration. If an interface were to extend a class, it would be inheriting behavior unless the class were purely abstract. Even in this case, the interface would be coupled to a specific class implementation, which defeats the purpose of separating the two.


When a class implements an interface that extends another interface, it must provide an implementation for all the methods in the interfaces, or be declared abstract.

The Body

The body of an interface contains the declarations for its methods and constants. Like a class, an interface body is enclosed in braces.

Methods

The main purpose of interfaces is to declare abstract methods that will be implemented in other classes. These method declarations take the form

  public  returnType nameOfMethod(  parameters  )  throws ExceptionList;  

where everything in italics is optional. As you can see, the syntax for declaring a method in an interface is nearly identical to declaring a method in a class, but a method in an interface cannot possess a body, even one that performs no operations. Just like an abstract method in a class, an interface method consists of only a declaration. For example, the following two method declarations are complete if they are defined in an interface:

 public double getPricePerUnit(); public void showState(); 

However, in a class, they would require method bodies unless they were declared as abstract:

 public double getPricePerUnit() {   return price; } // do-nothing implementation may not be useful // but an empty-bodied method declaration is valid // when there is no return value public void showState() { } 

When you declare an abstract method in a class, you must use the abstract keyword in the declaration. This makes your intent obvious to other programmers by clearly distinguishing abstract methods from those with empty bodies. An interface method declaration does not require the abstract keyword because an interface method has to be abstract. Using the keyword in the declaration would be redundant, so the compiler does not require it. Similarly, the public modifier is also assumed if you omit it. This differs from class methods where the default is package access if no modifier is specified.

Note

Although the compiler does not care whether you use the public and abstract modifiers when declaring interface methods, common practice is to include public but omit abstract.


A method declaration does not determine how a method will behave; it only defines what, if any, information it needs in the form of a parameter list and what, if any, information will be returned. An implementation of an interface method in a class must have the same properties as you define in the interface. This makes it important to carefully consider factors such as return type and parameter lists when defining an interface.

Note

Although optional, public and abstract are the only modifiers allowed in an interface method declaration. It is illegal to use any of the other standard modifiers (including native, static, synchronized, final, private, or protected ) when declaring a method in an interface. If an abstract method were private, it would be impossible for it to ever be implemented because only the current class can reference private methods. Similarly, a final method cannot be overridden. This is in direct conflict with an abstract method, which must be overridden. Several of the others ( native, static, and synchronized in particular) involve implementation details, so they are out of place in an interface.


Fields

Although interfaces are most often talked about in terms of their method declarations, they are also valuable for the constants they define. Declarations of constant interface fields take the form

  public static final  type FIELD_NAME = someValue; 

where everything in italics is optional. As with class fields, an interface field must be declared with a type and a valid identifier name. It might seem strange to you to see the specific modifiers public, static, and final listed as optional parts of the declaration. When you declare a class field, modifiers are optional in the declaration, but they are not restricted to such a narrow set of choices. These modifiers are listed as optional for interface fields, but the only optional part is whether you explicitly state them. Interface fields are required to be public, static, and final, so the compiler does not require you to include the modifiers. It is, however, a common practice to explicitly include the modifiers to remind yourself (and other programmers) of this fact.

As seen in the Steerable interface, interface fields ”just like final static fields in classes ”are used to define constants that can be accessed by all classes that implement the interface:

 public interface Steerable {   // define constants for directions to make sure   // that they are used consistently   String NORTH_DIRECTION = "North";   String SOUTH_DIRECTION = "South";   String EAST_DIRECTION  = "East";   String WEST_DIRECTION  = "West";   void turnLeft();   void turnRight();   String getCurrentDirection(); } 

Note

Unlike final class fields, you cannot declare an interface field using a blank final. Given that an interface has no method implementations, you have nowhere to assign the value to an interface field other than as part of its declaration. You are not prevented from using an expression, or even a method call, to perform this assignment, however. It is even legal for you to use an expression that assigns a different value each time your program is run. Remember that a constant is only required to maintain the same value throughout a single execution and not across executions. An interface's fields are initialized only once no matter how many instantiated objects implement it.


Some confusion over interface fields can occur when a class implements multiple interfaces that define a field with the same name. There is clearly a conflict because each interface could assign a different value to the same identifier name. In this case, you must reference the field using the interface name as a prefix, such as Steerable.NORTH_DIRECTION.

It is also possible for a class to inherit a field more than once if, for example, two of its super-interfaces extend the same class. In this case, an implementing class only has one copy of the field as far as the compiler is concerned , so it does not create any ambiguity.

Marker Interfaces

Although the interface declarations used in the examples so far contain at least one method, an interface is not required to declare any methods or fields. The following two interfaces are among the most important found in the Java API:

 package java.lang; public interface Cloneable { } package java.io; public interface Serializable { } 

Interfaces like these are called marker interfaces. Typically, an interface defines method signatures that impose a requirement on an implementing class to provide some associated behavior. Marker interfaces do not carry any requirements for behavior, but instead serve as an indicator that certain operations on a class are allowed.

The Cloneable interface demonstrates the use of a marker interface well. Remember that all classes, even those without an extends clause in their declarations, are a subclass of Object. Object defines a clone method that creates and returns a shallow copy of a class instance using a byte-by-byte copy of attribute values. If a class has only simple attributes, such as all primitive fields, this implementation is a valid one. However, a class that includes object references among its fields typically requires a more sophisticated procedure to create a deep copy of its instances. The Cloneable interface allows you, as the programmer, to state whether a valid clone implementation exists for a class you write. If you declare a class without stating that it implements Cloneable, a CloneNotSupportedException is thrown if the clone method in Object is called for one of its instances.

The serialization of class instances is discussed later in Chapter 22, "Object Serialization," but the Serializable interface is similar to Cloneable in that it identifies classes that support specific operations. Such a marker allows a class to be treated a certain way with some assurance that it will behave correctly.

   


Special Edition Using Java 2 Standard Edition
Special Edition Using Java 2, Standard Edition (Special Edition Using...)
ISBN: 0789724685
EAN: 2147483647
Year: 1999
Pages: 353

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net