OO2 Object Pascal
OO2 Object Pascal
class inheritance
Main concepts
Class inheritance.
Subclassing for reuse: extension, specialisation, generalisation.
Overriding inherited methods.
Encapsulation.
Visual Form Inheritance (VFI).
Delphis VCL class hierarchy.
Navigation (linkage) between objects.
Navigation on a UML class diagram.
Visibility for message passing.
Chapter contents
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Example 2.1 Subclassing through Visual Form Inheritance (VFI) . . . . . . . . . . . . . . . . . . . . . . . 2
Ex 2.1 step 1 The master form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Ex 2.1 step 2 The base class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Ex 2.1 step 3 A derived form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Ex 2.1 step 4 Another derived form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Ex 2.1 step 5 Linking the forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Example 2.2 Subclassing for extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Introduction to class inheritance (31 May 2006, all rights reserved) Chapter 2, Page 1
Ex 2.2 step 1 Extension in a subclass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Ex 2.2 step 2 A different extension in another subclass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Ex 2.2 step 3 Bidirectional communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Example 2.3 Subclassing for specialisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Ex 2.3 step 1 Specialising TForm3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Ex 2.3 step 2 Specialising TForm4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Example 2.4 Global and local declarations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Example 2.5 Hierarchies and generalisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Delphis VCL an example of subclassing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Help on the VCL hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Some concluding comments on inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Summary of class inheritance (subclassing) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Chapter summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Introduction
In this example, well use VFI to create the structure in figure 1. For now we show only the
class names and suppress the attributes and the methods in the class diagrams. Later
diagrams will show more detail.
Start a new application. Well write an event handler for this form (TForm1 in figure 1) to
display other forms (TForm3 and TForm4) in a moment, but for now, just change the size of
this TForm1 to about 300 x 1501.
VFI is the RAD process of creating a template form, the base class, and then inheriting (or
subclassing) other forms from it. First we create the base class.
Using File | New | Form, add a second form to the project (TForm2 in figure 1) and
place a button on it. This will form a base class from which we will inherit two subforms.
Make the form a convenient size (about 200 x 100) and create an OnClick event handler for
button1 in Unit2:
13 implementation
14 {$R *.dfm}
The descendant forms (TForm3 and TForm4 in figure 1) will inherit this method, and
well use the Sender parameter to identify the Caption of the button that has been clicked.
1
These dimensions refer to a low resolution screen. W ith higher resolution screens 452 x 225 or
600 x 300 may be better. It just needs to be a convenient size: big enough to use easily and small
enough not to obscure other forms.
Introduction to class inheritance (31 May 2006, all rights reserved) Chapter 2, Page 3
Line 17 is the first appearance of the Sender parameter and well see it several times again
through the course of this module.
TForm2, defined in step 2, is the base form from which we will derive further forms.
To create TForm3 in Delphi 4 to 7, select the menu sequence File | New | Other and then
select the Project1 tab (or Project2, 3, .... depending on the name of your current project).To
create TForm3 in Delphi 2005, select the menu sequence File | New | Other | Delphi
Projects | Inheritable Items. Form1 and Form2 are listed. Select Form2 (this is the base form
class from step 2), make sure that the Inherit RadioButton lower down is selected and click
OK.
Up until now, all our forms have been derived from TForm. Because we are using
TForm2 as a basis, Delphi derives our new form, TForm3 in Unit3, from TForm2 (line 7
below).
Units are encapsulated from each other, and so for Unit3 to be able to refer to TForm2 in
the class declaration (line 7), Delphi inserts Unit2, which defines TForm2, in the global uses
clause (line 5) of Unit3.
1 unit Unit3;
2 interface
3 uses
4 Windows, Messages, SysUtils, Variants, Classes, Graphics,
5 Controls, Forms, Dialogs, Unit2;
6 type
7 TForm3 = class(TForm2) // inherited from TForm2, not TForm
8 private
9 { Private declarations }
10 public
11 { Public declarations }
12 end;
13 var
14 Form3: TForm3;
15 implementation
16 {$R *.dfm}
17 end.
We can inherit any number of classes from an existing class, so inherit another new form
and unit (TForm4 in Unit4) from Form2 following the process outlines in step 3. Change the
Caption of the button on TForm4 to btnForm4. Position the four forms so that they do not
overlap, but dont change any other properties.
Inheritance means that the subclass inherits all the data fields and methods from the
superclass. Because this is a RAD application, the subclasses also have as default the initial
data values of the superclass. To see this, change, say, the width of Form2. The widths of
Form3 & Form4 change as well.
If youre in any doubt about what we have done so far, study the code for each of these
units and relate this back to figure 1.
We now have an inheritance structure with a number of different classes. However, a class
structure on its own does not do much we need to introduce some interaction paths
between the classes. We want to be able to display Form3 and Form4 from Form1. We can
extend our class diagram to show these paths (figure 3).
Introduction to class inheritance (31 May 2006, all rights reserved) Chapter 2, Page 5
Figure 3 Communication links
between classes
The UML convention uses closed, unfilled arrowheads for inheritance and open arrowheads
for navigation links (also called association links). Figure 3 shows open arrowheads on the
links between TForm1 and TForm3 & TForm4, pointing from TForm1 to the other two
forms. These reflect that Form1 can access Form3 and Form4, but that no access is available
in the reverse direction.
To implement these links, return to Unit1. Using the Component / Tool palette, place a
button on TForm1. Set its Name property to btnShowForms and its Caption to Show Forms.
Create an OnClick event handler for it that sends messages to Form3 and Form4, asking
them to Show themselves (lines 2021 below).
Press <F9>, ostensibly to run the program. Delphi will show an Information Box saying:
Form Form1 references Form3 declared in Unit3 which is not in your USES list. Do you
wish to add it? Click the Yes button for this question. Run it again. It repeats the question,
but this time for Unit4. Click Yes to add Unit4 to the uses clause as well. Delphi adds a local
clause uses Unit3, Unit4; to Unit1 (ie in its private, implementation section and not in the
public, interface section) (line 16 below).
15 implementation
17 {$R *.dfm}
Run the program again. Form1 (only) appears. Click on it to invoke its OnClick event
handler and Form3 and Form4 appear. Form2 does not appear because it has not been
instructed to Show itself. A Click on Form1 can send a Show message to Form3 and to
Form4 because there is an association between TForm1 and TForm3 and between TForm1
Neither TForm3 nor TForm4 have defined any data fields or operations. However they are
both derived from TForm2, which defines a TButton data field and its OnClick event
handler, and so both TForm3 and TForm4 inherit the button and its event handler from
TForm2. Thus, through inheritance, TForm3 and TForm4 reuse TForm2 and in this case do
not need any code of their own.
We set different Captions for the Buttons on Form3 and Form4 to show that we are
working with different objects. To identify these separate objects, we use the Sender
parameter in line 17 of Form2s OnClick event handler (example 2.1, step 2). Since every
instance has its own data, Form3 and Form4 also have their own values for Top, Left, and so
on, which is why they can take up different positions on the screen.
Save this project as well use it as a starting point for examples 2.2 and 2.3.
Example 2.1 Summary: The main OO principles in this example are inheritance and
communication. TForm2 inherits the knowledge of how to be a form from TForm. It adds its
own data field (a button) and a method (the buttons OnClick event handler). TForm3 and
TForm4 are both derived from TForm2 and neither adds anything of its own. Yet, because of
inheritance, each one has the knowledge of how to be a form (from the VCL class TForm),
and a button and its event handler (from TForm2). We also created navigation links (simple
association) between one form and another.
From a Delphi perspective, we have seen how with VFI we can define a base form
(Form2 in this case) and then derive further forms from it. We gained all the functionality
available in the base form without having to redefine forms separately as in chapter 1. The
buttons on the derived forms even all invoke the base forms event handler. So VFI is a
useful illustration of OO and inheritance and the way subclassing can promote reuse.
Introduction to class inheritance (31 May 2006, all rights reserved) Chapter 2, Page 7
Example 2.2 Subclassing for extension
In example 2.1 we didnt add any code to units 3 or 4. Because of inheritance each of their
Buttons uses the same event handler, the one inherited from the base form. However, a
subclass can also extend the superclasss functionality. Subclassing for extension involves
giving a subclass further features in addition to those it inherits. In this example well give
each subclass its own separate method: they will each manipulate Form1s position (figure
5).
We reflect the bidirectional navigability on our UML class diagram through double
openheaded arrows on the association links (figure 5). Here we show the relevant attributes
and methods that extend the superclass. To present a slightly different style, the inheritance
paths are shown as separate arrows, and not as combined tree graphs as in the previous
class diagrams.
Start with the program of example 2.1. Add a TCheckBox to Form3 (figure 6), give it the
Caption Top, and create an OnClick event handler by double-clicking on the CheckBox:
An important aspect of subclassing for extension is that each subclass can extend the
superclass differently. To see this, add an UpDown component (Win32 tab) to Form4 (figure
7), set its Wrap property to True, and create an OnClick event handler:
Here again, Delphi automatically inserts the inherited statement. We include a message
from Form4 to Form3 to clear the CheckBox whenever Form4 repositions Form1.
Introduction to class inheritance (31 May 2006, all rights reserved) Chapter 2, Page 9
Ex 2.2 step 3 Bidirectional communication
When using VFI we often send messages from one form to another, and in the steps above
both Form3 and Form4 communicate with Form1, and Form4 communicates with Form3.
We therefore need links between forms, and Delphi can often set these links up for us. To
see this, run the program (press <F9>). Delphi issues a series of messages informing us that
various form use other forms but do not include them in their respective uses lists. Click Yes
each time for Delphi to insert the appropriate uses clauses. Notice that Delphi inserts local
uses clauses into Unit3.pas and Unit4.pas (ie in the implementation section).
Attempt again to run the program. This time, when you show Form3 and Form4 by
clicking on Form1, each of these has the structure it derives from Form2 and also has its
own, individual extension that we have just introduced (figures 6&7).
Example 2.2 Summary: This example introduces subclassing for extension. Using inheritance for
extension has the characteristics that:
The subclass inherits all the functionality of the superclass,
The subclass adds new functionality,
The subclass makes no change to the (inherited) superclasss functionality.
Subclassing for extension is what people often have in mind when they extol the virtues
of inheritance as an important approach to the problem of reuse.
We also used this example as an opportunity to look briefly at bidirectional navigation
between objects and at representing navigation on a class diagram.
Another very important use of inheritance is subclassing for specialisation. Here, the subclass
is in some way a special case of the superclass and either overrides or extends the
superclasss methods. Well give Form3 its own additional Button1Click event handler to
extend the operation of the event handler it inherits.
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).
1 unit Unit3;
2 interface
3 uses
4 Windows, Messages, SysUtils, Variants, Classes, Graphics,
5 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}
19 end.
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.
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
Introduction to class inheritance (31 May 2006, all rights reserved) Chapter 2, Page 11
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.
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 implementation
17 uses Unit1;
18 {$R *.dfm}
Run 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
Example 2.3 Summary: In this example we have briefly explored inheritance for specialisation,
where a subclass specialises 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. We have not dealt with subtyping yet. Well come to
it in a little while and then see that interfering with the subtyping should be done only after
careful thought since it invalidates polymorphism, a central concept in OO.
Notice that with any RAD generated form, the unit defining the class (form) also declares a
global reference to an instance of that class in its interface section. This makes it possible for
any unit to access any form declared in another unit provided the appropriate uses clauses
are in place. To illustrate encapsulation, we can move the global declaration in Unit4 into
the implementation section to see what happens (lines 1213 below). (The implementation
section is accessible only to this unit.)
1 unit Unit4;
2 interface
3 uses
4 Windows, Messages, SysUtils, Variants, Classes, Graphics,
5 Controls, Forms, Dialogs, StdCtrls, Buttons, ComCtrls, Unit2;
6 type
7 TForm4 = class(TForm2)
8 procedure Button1Click(Sender: TObject);
9 end;
10 implementation
11 uses Unit1;
12 var
13 Form4: TForm4;
Introduction to class inheritance (31 May 2006, all rights reserved) Chapter 2, Page 13
14 {$R *.dfm}
19 end.
When we try to compile it, we get two error messages. Even though Unit1 has Unit4 in its
uses clause, Unit1 sees Form4 as an undeclared identifier because Form4 is now declared in
Unit4s (private) implementation section and not in its (public) interface section. To
emphasise that a declaration in the implementation section is only for a units local use,
Delphi generates a warning that variable Form4 is declared but not used in Unit4. Restore
the variable declaration to its rightful place before the implementation keyword and the
program functions correctly again.
Although we showed inheritance for extension and inheritance for specialisation
separately in examples 2.3 and 2.4, they often appear in combination. OO programs typically
involve quite a sophisticated network of derivation (through inheritance and composition)
and communication (through association).
Both extension and specialisation work from the perspective of an existing class that we
reuse to meet a new requirement by extending and/or specialising it in some way.
Hierarchical generalisation, on the other hand, looks at what is shared between a number of
existing classes (ie what is general between them) and then moves this common code out of
the existing classes into a superclass. By generalising these shared characteristics up into a
superclass from which the subclasses inherit, these shared characteristics need to be coded
only once, in the superclass, and can then be reused by the subclasses. Often the superclass,
like TForm2 in the previous examples, is not even instantiated but serves instead simply as a
way of storing the characteristics shared by its subclasses.
The mechanisms for both extension and specialisation and for generalisation are much
the same and the distinctions between these usually result from a particular set of
circumstances. Extension or specialisation often starts with an existing class which is
modified in some way to meet a new requirement. Generalisation often starts with the
identification of common characteristics between subclasses and results in the creation of a
possibly artificial superclass containing these shared characteristics.
Just as, in the previous examples, we can say that TForm3 and TForm4 either extend or
specialise TForm2, we can equally say that TForm2 generalises TForm3 and TForm4 since
While the principles weve looked at in the subclassing examples so far have been
important, the programs themselves have been trivial. 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 VCL2 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?
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 8
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.)
2
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.
Introduction to class inheritance (31 May 2006, all rights reserved) Chapter 2, Page 15
Figure 8 A partial, highly simplified diagram of Delphis VCL class hierarchy
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
The online Help provides a lot of documentation on the VCL Components. To explore this,
place a Timer on a form, select the Timer by clicking on it once with the mouse, and press
<F1> for Help. A short description appears (figure 9).
Introduction to class inheritance (31 May 2006, all rights reserved) Chapter 2, Page 17
Figure 9 Delphis VCL Help for the TTimer Component in Delphi 7
Near the top of the display is a list: Hierarchy, Properties, Methods, Events, Using TTimer.
Select Hierarchy. The display (figure 10) confirms the hierarchy illustrated in figure 8:
If we select the Properties link, we see a display of the properties that TTimer itself declares
and those it inherits from TComponent (figure 11). We can similarly get a display of
TTimers methods (figure 12). This is a much longer list than the properties, and if we scroll
down through the list we see methods from each of its ancestors.
In this chapter we have been looking at inheritance for subclassing. There is also another
form of inheritance called subtyping. Subtyping is linked to the concepts of late (or dynamic)
binding and polymorphism. Polymorphism (and subtyping) are important and powerful
aspects of object orientation that allow us, for example, to introduce additional subtypes into
a system with minimal impact on the rest of the program, so simplifying future changes. We
will return later to look at this in more detail.
Multiple inheritance
Delphi, like Java and unlike C++, does not implement multiple inheritance. To achieve an
effect similar to multiple inheritance in Delphi or Java, we can use composition and/or
interfaces. We will return to this when we look at composition.
Introduction to class inheritance (31 May 2006, all rights reserved) Chapter 2, Page 19
Composition an alternative to inheritance
While inheritance is very powerful and useful, it is not the only the way to re-use existing
classes, and in some situations composition is preferable. Composition is a way to combine a
group of objects to create a super-object. Delphi uses it extensively in generating user
interface forms In example 1.2, for instance, the user interface (class TfrmStructureDemo) is
derived from the TForm type and contains two Buttons and two methods (the event
handlers). We can see this by looking at the type declaration in that program:
type
TfrmStructureDemo = class(TForm)
btnYellow: TButton;
btnBlue: TButton;
procedure btnYellowClick(Sender: TObject);
procedure btnBlueClick(Sender: TObject);
end;
btnYellow and btnBlue are part of the TfrmStructureDemo class: TfrmStructureDemo HasA
btnYellow and btnBlue. Figure 3 of chapter 1 implies composition. As we saw in figure 5 of
chapter 1, we can redraw this diagram to emphasise it, using a diamond shape to indicate
composition (figure 13 below). We use multiplicity indicators on the link to show that the
TfrmStructureDemo class is composed of two TButtons.
In summary, building a class from one or more other classes is called composition. The aim
behind composition is similar to inheritance to be able to re-use existing objects and classes
and so to write code only for additional characteristics. In OO, composition and inheritance
are two major tools for creating new classes and for reuse.
Well investigate composition in chapters to come.
Subclassing facilitates reuse through programming by difference since the subclass IsA
superclass. All the superclasss data fields and methods are available to its subclasses
(except for data and methods in the superclass that have private scope). Since the subclass
inherits the superclasss functionality it needs to implement (only) the additional data fields
and methods and the override methods (figure 14).
Extension: With extension, the subclass adds new functionality (MoreData, MoreMethods
and ExtraData, ExtraMethods in figure 14) but makes no changes to the superclasss
existing functionality.
Specialisation: With specialisation, the subclass is a special case of the superclass and so
extends or overrides some of the superclasss methods (OverrideMethods1 &
OverrideMethods2 in figure 14). Excessive use of specialisation may indicate the need for
a redefinition of the hierarchy, particularly where it completely replaces the superclasss
behaviour, since this invalidates the subtyping.
Generalisation: For generalisation, create a (possibly artificial) superclass. Remove the
common data and functionality found in the subclasses and implement these in the
superclass (generalise up). Do this repeatedly between each set of levels in the hierarchy.
The consequence is that the common functionality, ie the generalisations common to the
subclasses, is found in the superclasses. The specific functionality, ie the extension and/or
specialisation, is found in individual subclasses The classical example of a generalisation
hierarchy is the biological taxonomy (eg a cat IsA mammal IsAn animal ...).
Introduction to class inheritance (31 May 2006, all rights reserved) Chapter 2, Page 21
Although we have treated these three different types of subclassing separately, they are
often combined in practice. Its quite possible and common for a single subclass both to
extend a superclass and to specialise an aspect of the superclass, and for the superclasses to
have been identified through a process of generalisation.
Chapter summary
Main points:
1. Visual Form Inheritance (VFI): RAD generated reuse of user interface classes.
2. Visual Component Library (VCL): Generalisation, inheritance for reuse.
3. Reuse: Inheritance for extension, specialisation (through overriding) and generalisation.
Problems
Some of the problems in chapter 3 test principles covered in this chapter.
Identify the appropriate example(s) or section(s) of the chapter to illustrate each comment
made in the summary above.
Introduction to class inheritance (31 May 2006, all rights reserved) Chapter 2, Page 23