Ex 2.3 step 1 Specialising TForm3
Open the project from example 2.1. (If you dont want to overwrite it, save all the units and project file in a different subdirectory for use in this example).TForm3 and TForm4 are empty classes that inherit all their functionality (TForm2s OnClick event handler) from TForm2. We are going to specialise this OnClick event handler in the subclasses by adding extra functionality to it in TForm3 and in TForm4. In design mode, select Form3 and double-click on Button1. Delphi creates an event handler skeleton. Add the additional line of code shown below (line 17).
1 unit Unit3;Run this program. Clicking on the button in Form3 brings up the original message generated by TForm2s Button1Click event handler (example 2.1, step 2, line 17). Accepting this message then brings up another message generated by TForm3s Button1Click event handler. By contrast, clicking on the button in Form4 gives just the functionality derived from Form2.
2 interface
3 uses
4 Windows, Messages, SysUtils, Variants, Classes,
5 Graphics, Controls, Forms, Dialogs, StdCtrls, Unit2;
6 type
7 TForm3 = class(TForm2)
8 procedure Button1Click(Sender: TObject) ;
9 end;
10 var
11 Form3: TForm3;
12 implementation
13 {$R *.dfm}
14 procedure TForm3.Button1Click(Sender: TObject) ;
15 begin
16 inherited;
17 ShowMessage ('Another msg from ' + (Sender as TButton).Caption) ;
18 end;
19 end.
So with TForm3 we have a case where we use inheritance to add to the inherited functionality, a process called specialisation.
Lets look at what is happening here. When you double-click on the Button1 in Form3 during design mode, Delphi creates a new Button1 event handler as a method of TForm3 (declared in line 8 above). For any object of class TForm3, the OnClick event handler in TForm3 will override the inherited event handler in TForm2. (By contrast, TForm4 does not declare its own event handler, so Form4 therefore goes up a level and executes the event handler inherited from TForm2.)
Delphi also generates the event handler skeleton (lines 1416 & 18 above). Whats different here from the event handler skeletons we saw in chapter 1 is that Delphi inserts an inherited statement (line 16 above and also in the event handlers in example 2.2). Why is this? Usually, with specialisation, we want to add some functionality to that available from the superclass. However, in the previous paragraph we said that the event handler in the derived class completely replaces the event handler defined in the superclass. The inherited keyword in the subclass method calls the corresponding method in the superclass.
So the subclasss method overrides completely the method in the superclass. If we still want the (overridden) superclasss method to run, we insert the inherited keyword, usually as the first statement in the (overriding) subclasss method.
Having called and executed the superclasss method, we now move on to line 17, which provides the specialisation operations.
For interest, you may wish to change the order of lines 16 &17 and then run the program again. The message from TForm3s Button1Click now appears before TForm2s.
Ex 2.3 step 2 Specialising TForm4
We can give TForm4 a different specialisation to TForm3. We will also completely override the superclasss method by deleting the inherited statement that Delphi inserts automatically. Select Form4, double-click on its Button1 and create the following event handler, remembering to remove the inherited statement.Because this event handler refers to Unit1, this unit also needs a uses Unit1 clause. You can insert this yourself (line 17 below) or have Delphi insert it for you as before. (Unit3 does not refer to Unit1, and so we did not insert a uses Unit1 clause in step 1 above.)
16 implementationRun this program. Clicking on the button in Form4 repositions Form1 with its top at 300 pixels without displaying any message. The event handler in the superclass does not run because TForm4s Button1 OnClick event handler (lines 1518 above) does not contain the inherited keyword and so does not invoke the superclasss (TForm2s) Button1 OnClick event handler.
17 uses Unit1;
18 {$R *.dfm}
19 procedure TForm4.Button1Click(Sender: TObject) ;
20 begin
21 Form1.Top := 300;
22 end;
Example 2.3 Summary:
A subclass can specialis a superclasss functionality. This specialisation can be additional code to that in the superclasss method, in which case the subclass method contains the inherited keyword. The specialisation can also completely replace the superclasss method, in which case the subclasss method does not contain the inherited keyword.
A word of caution: when we completely replace the superclasss method in the subclass we affect the subtyping of the subclass. Interfering with the subtyping should be done only after careful thought since it invalidates polymorphism, a central concept in OO.
Next time: inheritance in the VCL!

