Ex 6.1 step 2 Testing the classes
Well use the Form and Unit1 to write a driver program. To add the RadioGroupBoxs Items.Strings, select the RadioGroupBox and click on the three dots alongside the Items property in the Object Inspector. The property editor appears. Enter Furniture, Chair, Table, each on a new line.Notice that we add a private data field of type TFurniture to our user interface class (ie to the form) in line 16 below and so we must add FurnitureU to the uses clause (line 5).
unit SubstitutionU;
interface
uses
5 FurnitureU, Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type
TfrmSubstitution = class(TForm)
btnKind: TButton;
lblKind: TLabel;
btnFree: TButton;
rgbFurniture: TRadioGroup;
procedure btnKindClick(Sender: TObject) ;
procedure btnFreeClick(Sender: TObject) ;
procedure rgbFurnitureClick(Sender: TObject) ;
private
MyFurniture: TFurniture;
end;
var
frmSubstitution: TfrmSubstitution;
implementation
{$R *.DFM}
procedure TfrmSubstitution.rgbFurnitureClick(Sender: TObject) ;
begin
FreeAndNil (MyFurniture) ;
case rgbFurniture.ItemIndex of
26 0: MyFurniture := TFurniture.Create;
27 1: MyFurniture := TChair.Create;
28 2: MyFurniture := TTable.Create;
end;
lblKind.Caption := '';
end;
procedure TfrmSubstitution.btnKindClick(Sender: TObject) ;
begin
if MyFurniture = nil then
lblKind.Caption := 'Object not defined'
else
lblKind.Caption := MyFurniture.GetKind;
end;
procedure TfrmSubstitution.btnFreeClick(Sender: TObject) ;
begin
if MyFurniture = nil then
lblKind.Caption := 'No object exists'
else
begin
FreeAndNil (MyFurniture) ;
lblKind.Caption := 'Object freed'
end;
rgbFurniture.ItemIndex := -1;
end;
end.
Lines 27 and 28 are interesting. MyFurniture is declared as a TFurniture (line 16) and so it is no surprise that we can assign it to an instance of TFurniture in line 26. But in lines 27 and
28 we assign a reference of type TFurniture to instances of types TChair and TTable. We can do this because TChair and TTable are derived from TFurniture and so we can take advantage of substitution.
Run this program and test it. Clicking any of the RadioButtons and then the Kind button displays the message Furniture. We see the same message whether MyFurniture is a TFurniture, a TChair or a TTable since line 37 above invokes the GetKind method defined in TFurniture (step 1 lines 1417) through the inheritance relationships between the classes.
But wouldnt it be nice if the TChair instance could declare itself to be a chair and the TTable instance show that it is a table? We do this in the next step. But just before doing that, notice the care taken in this program about creating and freeing the object and testing for its existence. Since an object continues to exist after the event handler rgbFurnitureClick completes, the other two event handlers both start with a test for its existence.

