To see a very effective application of subclassing which involves extension and generalisation, and to a less obvious extent, specialisation, we need look no further than Delphis Visual Component Library (VCL).
The VCL provides the components (via the Component / Tool palette) for building up the user interface. If we look at the available components on the Component / Tool palette, we notice that they have varying degrees of similarity and difference.
Comparing a TButton and a TLabel, we see that there are similarities between them: they are both visible on a form at a specific position and so on. But we also see major differences.
However, if we compare a TButton and a TBitBtn we see that the similarities are much greater. How do we accommodate varying degrees of similarity and difference effectively?
Note: Version 6 of Delphi and later also contain the CLX library, introduced for portability with Linux. Version 8 includes the .NET library. Here well just stick with the original VCL which is common to all versions.
In principle, wed like to code whatever is the same between components only once and to use new code exclusively for the additional characteristics in the new component. OO systems make this possible through the class hierarchy and inheritance. Figure shows a highly simplified representation of Delphis VCL class hierarchy. (A set of standard utility classes like the VCL has an extensive and deep hierarchy. Class hierarchies we define ourselves are usually much shallower.)
In a hierarchy like this we look for commonality between the various components and then code this commonality in a (possibly artificial) superclass. Following this approach, we take whatever is common between a TLabel, a TButton and a TForm and code this in a new class, TControl. We now look at what is common between TTimer, TControl and TMenu and code this in a new class, TComponent and so we continue up the hierarchy. We may never instantiate the higher level classes such as TControl, TComponent or TPersistent. Instead they provide the opportunity to code shared characteristics once only in an ancestor. All the descendants then use this code instead of writing it over from scratch each time.
Looking specifically at the VCL, whatever is fundamental to all components and objects appears as high as possible in the hierarchy, in the base class. All Delphi classes must be able to create and destroy instances of themselves and so TObject, which is the root of Delphis inheritance hierarchy, has these abilities.
All Delphi objects except for Exceptions and TStream objects can be saved, and so the next level of the hierarchy separates those that can be saved (TPersistent) from exceptions and TStream objects. Some persistent classes are components and others are not, and so the TComponent type appears below TPersistent in the hierarchy.
TComponent introduces the ability to appear on the Component / Tool palette and to be manipulated in the Form Designer, and properties such as Name. It also inherits the ability to be saved from TPersistent and to create and destroy objects from TObject via TPersistent.
Some components are visual and others, like TTimer or TMenu, are not. Visual components are visible at run-time and so they need additional abilities such as Left and Top to give their position on the form, the pop-up hints and the ability to respond to mouse actions. These abilities are packaged in TControl. Thus, unvisible component are called Controls.
Going further down the hierarchy we finally reach the actual components that we use in our programs, such as TLabel and TButton. These inherit all the abilities available in TControl which in turn inherits all the TComponent abilities, which in turn inherits all the TObject abilities. Common abilities are coded high up the hierarchy, and are available to all the classes lower down that branch of the hierarchy.
Each new level in the hierarchy need only code additional abilities and does not need to repeat what is available from higher up. So the more general the characteristic, the higher up the hierarchy it is coded. The more specialised characteristic, the lower down it is coded. This characteristic gives rise to phrases like generalisation hierarchy and to the term generalisation that UML uses when referring to inheritance.
As we saw, TControl introduces properties for Left and Top, and so it and all its descendants have the Left and Top property. Referring to VCL Figure, we see that TControl, TLabel, TButton, TForm and TBitBtn all have the Left and Top properties. However, TMenu, TComponent and TObject, which are not descendants of TControl, do not inherit the Left and Top properties.


