Ex 6.4 step 3 A helper method in the superclass
Going back to the definition of TMyShape and its descendants we see that both GetKind methods have the same statement to clear the Image component and to place a border around it (example 6.4 step 1 lines 22 & 29). Although this repetition is not crucial in a small example like this, in principle we try to avoid duplication by placing repeated code into a separate method, sometimes called a helper method because it is for use only within the class. If we declare this method as part of the base class, as we do here in lines 910 below, each subclass can access it through inheritance rather than defining it separately a nice bit of reuse.What kind of visibility should we assign to a helper method like this? We dont want to make it public since other units would then also be able to use it, compromising encapsulation. Here we define TMyShape, TMyEllipse and TMyRectangle in the same unit. Delphis visibility specifiers apply to a unit2, and so we can specify the parents helper methods as private: the subclasses can still access them. If we code the subclasses in separate units, we would have to make the helper method protected. This makes it accessible to the parents class descendants, even if they are in a different unit, but not to anyone else.
Here we declare the helper method as protected in the superclass (lines 910) and invoke it from the subclasses (lines 24, 31).
unit MyShapesU;
interface
uses ExtCtrls;
type
TMyShape = class (TObject)
public
procedure Draw (AnImage: TImage; ABorder: integer) ; virtual; abstract;
protected
procedure Clear (AnImage: TImage) ;
end;
TMyEllipse = class (TMyShape)
public
procedure Draw (AnImage: TImage; ABorder: integer) ; override;
end;
TMyRectangle = class (TMyShape)
public
procedure Draw (AnImage: TImage; ABorder: integer) ; override;
end;
implementation
{ TMyEllipse }
procedure TMyEllipse.Draw(AnImage: TImage; ABorder: integer) ;
begin
Clear (AnImage) ;
AnImage.Canvas.Ellipse (ABorder, ABorder, AnImage.Width - ABorder, AnImage.Height - ABorder) ;
end;
{ TMyRectangle }
procedure TMyRectangle.Draw(AnImage: TImage; ABorder: integer) ;
begin
Clear (AnImage) ;
AnImage.Canvas.Rectangle (ABorder, ABorder, AnImage.Width - ABorder, AnImage.Height - ABorder) ;
end;
{ TMyShape }
procedure TMyShape.Clear(AnImage: TImage) ;
begin
AnImage.Canvas.Rectangle (0, 0, AnImage.Width, AnImage.Height) ;
end;
end.
Pattern 6.1 Polymorphism
At times, alternative behaviour is needed on the basis of an objects type. One approach to this is to use a series of If statements that test the objects type and then invoke the required behaviour. However there are several problems associated with sets of If statements. They can rapidly become complex, making it difficult to test them and to modify them, particularly if similar If evaluations are needed at different stages of a program.Therefore, when the required behaviour is determined by the type of an object, consider using a polymorphic call instead of using an If statement. The programmer then does not need to encode the logic for determining the type since the resulting behaviour is a product of both the method call and the receiving object. Future changes, such as additional classes of the same subtype, are accommodated by the polymorphic methods of the new classes rather than by extending If statements. Thus the types that vary have the responsibility for the correct behaviour. This reduces the possibility of introducing errors when If statements have been changed incorrectly or have been overlooked.
Polymorphism therefore can make code simpler to implement and more reliable. Because polymorphism relies on substitution, and so on the generalisation hierarchies in the program, designing for polymorphism can improve the class inheritance structure and reduce coupling. (A single association link can be used to navigate between all descendants of the two associated classes.) The drawbacks of polymorphism are that it can make code more difficult to understand and can introduce additional classes into the program structure.
Polymorphism is a crucial difference between object-oriented programming and other programming styles. Used carefully, polymorphism produces systems that are simpler and also more flexible, and so can be changed more easily to meet changing requirements. It plays an important role in many patterns, and well be meeting it regularly in the remaining chapters.

