THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

Similarly, if an interface inherits more than one method with the same signature, or if a class implements
different interfaces containing a method with the same signature, there is only one such method. The
implementation of this method is ultimately defined by the class implementing the interfaces, and there is no
ambiguity there. If the methods have the same signature but different return types, then one of the return types
must be a subtype of all the others, otherwise a compile-time error occurs. The implementation must define a
method that returns that common subtype.


The real issue is whether a single implementation of the method can honor all the contracts implied by that
method being part of the different interfaces. This may be an impossible requirement to satisfy in some
circumstances. For example:


interface CardDealer {
void draw(); // flip top card
void deal(); // distribute cards
void shuffle();
}
interface GraphicalComponent {
void draw(); // render on default device
void draw(Device d); // render on 'd'
void rotate(int degrees);
void fill(Color c);
}
interface GraphicalCardDealer
extends CardDealer, GraphicalComponent { }


Here it is difficult to write an implementation of draw() that can satisfy the two different contracts
independently. If you try to satisfy them simultaneously, you are unlikely to achieve the desired results:
flipping a card each time the screen gets repainted.


As with overriding in class extension, the overriding method is not permitted to throw more checked
exceptions than the method it overrides. If two or more method declarations are inherited, without overriding,
and differ in the exceptions they throw, then the implementation of that method must satisfy all the throws
clauses of those declarations. Again the main issue is whether such distinct methods can have a single
implementation that honors all contracts. We look further at the issues of overriding and exception throwing
in Chapter 12.


If a declared method has the same name but different parameters from an inherited method, then the declared
method is an overloaded form of the inherited method. The eventual class implementation will provide a
method body for each of the overloaded forms.


If a declared method differs only in return type from an inherited method, or if two inherited methods differ
only in return type where one type is not a subtype of the other, you will get a compile-time error.


4.4. Working with Interfaces


The previous chapter introduced the Attr class and showed how to extend it to make specialized types of
attribute objects. Now all you need is the ability to associate attributes with objects.


The first decision to make is whether having attributes is reflected in the type of the object. An object could, if
you chose, contain a set of attributes and allow programmers access to that set. Or you could say that being
able to store attributes on an object is a part of its type and so should be part of the type hierarchy. Both
positions are legitimate. We believe that representing the ability to hold attributes in the type hierarchy is most
useful. We will create an Attributed type to be used for objects that can be attributed by attaching Attr
objects to them.

Free download pdf