< Day Day Up > |
Polymorphism deals with manipulating objects of different classes using only the interface that they have in common. There are two different uses for polymorphism . In the first case, there are different implementations of an interface with the same behavior, such as with printer drivers. In the second case, there are different behaviors with the same interface, such as proxy classes with different operations. You can code classes to be polymorphic in two ways. [*] One way is to use inheritance. Derived classes share the interface of the base class. The second way is to implement interfaces in languages such as Java and C#.
6.4.1. Using InheritanceA typical example of an inheritance hierarchy has a Shape base class. Shapes such as Rectangle and triangle are derived from Shape , as shown in Figure 6-1. A Square shape is then derived from Rectangle , and an EquilateralTriangle is derived from triangle . An EquilateralTriangle and a Square have a facet in common that is not represented in this inheritance hierarchy. They both represent regular polygons (all their sides are the same length). 6.4.2. Using InterfacesInstead of using inheritance, you could code the relationship with interfaces, as shown in Figure 6-2. When Square s and EquilateralTriangle s are added, they can implement a RegularPolygon interface as well as the Shape interface, as shown in Figure 6-3. The disadvantage of using interfaces is that each class that implements an interface must code each method in the interface. For example, EquilateralTriangle and Square both need to have code for the set_length_of_side( ) method. If the code is the same, the common Figure 6-1. Shapes using inheritanceFigure 6-2. Shapes using an interfacecode could be placed in a set_length_of_side( ) method in a RegularPolygonImplementation class. The set_length_of_side( ) methods in EquilateralTriangle and Square would call that method. An advantage of using interfaces is that the relationship between the classes is fluid. After having experience in using the classes, you might find that RegularPolygon s actually have a lot more in common than a Square and a Rectangle . Instead of prematurely creating an inheritance hierarchy that ties Square into Rectangle , thinking in interfaces allows these relationships to develop. Figure 6-3. Shapes using an additional interface
Frameworks that use inheritance can often be designed with interfaces. For example, a Component class is often the base class of a GUI hierarchy, as shown in Example 6-1. With inheritance, it can be unclear which methods of the base class should be overridden by derived classes. Example 6-1. Component with inheritanceclass Component { draw( ); hide( ); } class MyComponent extends Component { // What should it override? } Alternatively, the class could require that an interface be implemented, as shown in Example 6-2 and Figure 6-4. Custom components would implement the interface, which makes clear what methods need to be created. Example 6-2. Component with delegation to interfaceinterface Component { draw( ); } class BaseComponent { Component a_component; draw( ) { a_component.draw( ); } } class MyComponent implements Component { draw( ) { // Particular draw } } Figure 6-4. A framework using strategy |
< Day Day Up > |