FURTHER CLASS TECHNIQUES Aims
To enable
students to: ·
handle
abstract classes ·
call
inherited constructors ·
make
friends ·
use
multiple inheritance Handle abstract
classes
Frequently
classes within hierarchies do not represent anything concrete enough to be
instantiated in their own right. Such a class is a ‘holder’ for methods and
attributes shared between derived classes. Within a large hierarchy there may
be several abstract classes in existence at different points in the structure. For
example, in an ‘animal’ hierarchy there will probably be several layers of abstraction.
The beginning may be a base ‘animal’ class containing attributes and methods
common to all animals. From here more specific, but still abstract, classes can
be derived - such as mammals and birds. Only specific classes at the bottom of
the hierarchy represent concrete types of animals. Use of the virtual keyword can ensure that abstract classes can not be
instantiated within a program. Methods within a class may be marked as being
‘pure virtual functions’ by the following syntax within the class definition: virtual
data type method_name () = 0; This means
no implementation is provided or the method within this class, implying: ·
The
method can not be invoked by objects of derived classes, unless an overriding
implementation is provided ·
No
objects of the class containing the virtual method may be instantiated As an
example, an animal class could be represented by class
CAnimal { public: virtual void move (int iDirection) = 0; … } And a
specific creature could be represented as follows, not in this case several
other classes (such as mammal and pig) have been passed through to reach this
point: class
CSaddleBack:: public CPig { public: void move (int iDirection); … } Call inherited
constructors
A derived
class always calls the constructor of the base class besides its own. The base
class constructor is always called first, followed by the derived class, and so
on down the tree if there are several levels of inheritance. If the base
class takes no parameters then the constructor inheritance is implicit, but if
parameters are involved then they must be stated explicitly in each derived
class. In the
following example, a fragment of a customer class takes the customers name as
an argument to its constructor. Class
CCustomer { private: char customer_name[30]; public: CCustomer (char *name_in) { strncpy(customer_name, name_in, 29); customer_name[29]=’\0’; } } Any
constructors of the derived class must pass a value to the constructor of
CCustomer. In the following example CAccountCustomer takes both an account
number and customer name. Note, the colon operator is used to indicate
inheritance. class
CAccountCustomer :public Customer { private: int account_number; public: CAccountCustomer (int ACNumber, char
*name_in); } CAccountCustomer::CAccountCustomer
(int ACNumber, char *name_in) : Customer(name_in) { … } Derived
classes also inherit base class destructors, but they are called in the reverse
order to constructors. Since class destructors take no arguments, explicit
parameter inheritance is not an issue. Make friends
Member
functions and variables declared as private to a class are normally viewed as
being inaccessible to objects of other classes. However, it is possible to
break this rule via the friend qualifier. A
declaration of the form: friend
class CGeorge; allows all
members of the class CGeorge to access both protected and
private members of the class in which the declaration is placed, for example: class
CSue { friend class CGeorge; public: … } declares
that CGeorge is viewed as CSue as a friend, though it says nothing about how CGeorge views CSue. It is
possible to restrict access to specific functions in another class by giving a
declaration of the form: friend
CSally::peek (int); which
grants only the peek function of class CSally access to the classes protected and private members. Use multiple
inheritance
Inheritance
is based on ‘a kind of’ relationships, so that if class A inherits from class
B, it can be said that class A ‘is a kind of’ B. As an example an oak is ‘a
kind of’ tree, this is an example of single inheritance where a class is
derived from a single base class. Sometimes
single inheritance is not enough to describe relationships that exist between
classes. For example tow classes may exists, tree and flowering plant. A
flowering tree is both a tree and flowering plant, a case can be made for
deriving it from both of the base classes since it has the characteristics of
both. Multiple
inheritance does not often prove necessary in an object oriented system, indeed
many object oriented languages do not even support it. It allows information
from more than one source to be mixed easily and extends the circumstances in
which existing classes may be reused. However, complexity is increased and
conflicts may arise between inherited attributes and methods. If elements
of the inherited bases classes overlap then ambiguity exists in the inheritance
hierarchy. Ambiguity arises in the following situations: 1. A derived class inherits two methods
of the same name but different implementations from multiple base classes 2. A derived class overrides a multiply
defined inherited methods, but calls a base class method as part of its
implementation. 3. A derived class accesses an
attribute or method inherited from a single ancestor by multiple base classes. To overcome
these ambiguities programmers must specify which method or attribute is
required via the scope resolution. For example a developer may wish to extend common_function () defined in the base class CBaseClass1 and not that provided by CBaseClass2. This is achieved using the applying scope
resolution to the function call as in CBaseClass1::common_function
(). Obviously
multiple inheritance imposes some extra work on developers. When should this
technique be used over others, such as aggregation? A number of factors should
be considered when deciding on which technique to use ·
What
are the semantics of the objects - is the new object ‘a kind of’ more then one
other object, or are the other objects ‘a part of’ our new object, or just
other discrete objects with which the new object should communicate? ·
Will
aggregation be simpler to implement? ·
What
ambiguities need to be overcome? ·
Is it
necessary for our new object to be a derived class? Many object management
mechanisms, such as containers, require a consistent set of interfaces for all
the objects they send messages to. This consistency is achieved through base
classes. Questions
Create a
small animal hierarchy ensuring the base classes can not be instantiated via
pure virtual functions. The name of the animal, for example a robin, is an
attribute of the base class set by its constructor. Ensure that constructor
inheritance is used to set this variable. Investigate
how a thermostat connected to a heating system can be designed and implemented.
You should consider aggregation, multiple inheritance and monolithic solutions.
Your thermostat should be a simple device which will turn the heating on and
off depending on temperature. It will consist of at least two underlying
elements, a temperature gauge and a switch. |
|
||
|
|||
|
Last updated: 11th July 2006. copyright © 2006 Greystoke Systems Ltd. Web address: http://www.gsys.biz/Documents/Services/Tuition/CityAndGuilds/FurtherWork/FurtherClassTechniques.htm |