Ex 6.3 step 2 Calling additional subclasses
Extend the user interface as shown in figure 6 by adding the items CoffeeTable and KitchenTable to rgbFurniture. Extend the rgbFurnitureClick event handler as shown:procedure TfrmSubstitution.rgbFurnitureClick(Sender: TObject) ;The only programming change we have to make in the client class is to instantiate and assign these two new subclasses. Because of the late (runtime) binding, we make no change in the statement that uses these instances. This is the power of polymorphism. Each subclass knows how to do whatever it needs to do as a result of its own and its inherited methods. If these methods allow runtime binding, the program knows which method to call depending on the identity of the object. This means that if we add additional subclasses to an existing program we do not have to go through the program adding calls to these new subclasses. Because of polymorphism the correct methods will be called automatically.
begin
FreeAndNil (MyFurniture) ;
case rgbFurniture.ItemIndex of
0: MyFurniture := TFurniture.Create;
1: MyFurniture := TChair.Create;
2: MyFurniture := TTable.Create;
3: MyFurniture := TCoffeeTable.Create;
4: MyFurniture := TKitchenTable.Create;
end;
lblKind.Caption := '';
end;
procedure TfrmPolymorphism.btnKindClick(Sender: TObject) ;
begin
if MyFurniture = nil then
lblKind.Caption := 'Object not defined'
else
lblKind.Caption := MyFurniture.GetKind;
end;
In essence, the program merely needs to tell an object to do XYZ. Each different class in the hierarchy knows how it must do XYZ and so goes ahead and does it. The program using the object is not concerned with how the object performs the required operation, just that it does whatever is appropriate.
To see this in action, run the program. Select a RadioButton and then click on the Kind Button. A message identifying the selected object and its ancestors appears. Even though there is only one instruction causing the display, each object knows who it is and what its ancestry is and so creates a different display despite receiving the identical message.
Polymorphism simplifies the process of modifying and evolving a program and minimises the impact on the client of adding or removing classes. (The polymorphic call in line 43 above is completely unaffected by the addition or subtraction of TFurniture descendants since it relies only on the GetKind method signature.) Substitution also reduces coupling between objects since an association link is valid for the designated class and all its descendants. (The private field in TfrmSubstitution that holds a reference to TFurniture (example 6.1, step 2, line 16) enables a TfrmSubstitution instance to be associated with an instance of any of the five classes in the TFurniture hierarchy.)
That's it for this chapter. Next time we'll take a look at abstract methods.

