1 object oriented programming development - week8 z rob manton z email: [email protected] z...
TRANSCRIPT
2
Module Outline
IntroductionNon object
oriented basicsClasses
InheritanceAggregationPolymorphismMultifile
Development
3
Today:
Some advice for next week’s test
Inheritance recap
Aggregation
4
Practical Test in Week 9
Tuesday 26th November in two sittings
5-6pm and 6.15-7.15pm
Will involve writing a simple class
instantiating objects
other C++ constructs as practised in the
lab sheets to date
inheritance and or aggregation
5
Last week: Inheritance
Inheritance allows classes to inherit attributes and methods from other classes in a classification hierarchy
6
Last week: Inheritance
Inheritance allows
specialisation (extending the functionality of an existing class)
generalisation (sharing commonality between two or more
classes)
7
Last week: Inheritance
Inheritance is appropriate where a class can be said to be ‘a kind of’ other class
Car
Vehicle A car is ‘a kind of’ vehicle
car class can inherit from
vehicle class
8
Last week: Inheritance
Inheritance is appropriate where a class can be said to be ‘a kind of’ other class
Car
Wheel A wheel isn’t ‘a kind of’ car.
A wheel is ‘a part of’ a car
- this is dealt with by aggregation
which is this week’s topic
9
Last week: Inheritance
Inheriting from a class doesn’t affect the integrity of that class - objects of the original base class can still be created
Generalisation allows removal of redundancy and duplication among classes
Some base classes are abstract - they are not specific enough to be instantiated but act as holders for common attributes and methods of derived classes
10
Last week: C++ Syntax
The colon (:) operator to denote inheritance
Public and private derivation of object methods from a base class
The ‘protected’ keyword to allow derived classes to access inherited attributes
11
C++ Syntax: public derivation
Class DerivedClass: public BaseClass{private:
int y;public:
void setY(int y_in); int getY();
}
A derived class.The colon operator means
the derived classinherits from the base class
12
C++ Syntax: public derivation
Class DerivedClass: public BaseClass{private:
int y;public:
void setY(int y_in); int getY();
}
the public derivation means that objects of the derived classcan access the public methodsand attributes of the base class
This is the most usual typeof derivation
13
C++ Syntax: public derivation
class BaseClass { private:
int x; public:
void setX(int x_in); int getX();
};
class DerivedClass: public BaseClass { private:
int y; public:
void setY(int y_in); int getY();
};
Main(){BaseClass base_object;DerivedClass derived_object;
base_object.setX(7);
derived_object.setX(12);derived_object.setY(1);
return 0;}
Object of the derivedclass can access methods
of the derived classand also methods of the
base class
14
C++ Syntax: public derivation
Publicly derived classobjects of this class are
able to call public methodsof the base class
Public derivation is themost common type
15
C++ Syntax: private derivation
Changed to a Privately derived class
objects of this class are NOTable to call public methods
of the base class - this won’tcompile!
16
Last week: public/private inheritance
Public inheritance allows all public methods of ancestor classes to be available to objects of a derived class
Line
Attributes:start positionend position
Methods:draw
Coloured Line
Attributes:colour
Methods:setColour
Class ColouredLine: public Line{….};
main(){ColouredLine myLine;myLine.draw();} Object of derived class
can access method ofbase class
17
Last week: public/private inheritance
Private inheritance prevents objects of the derived class from calling the public methods of the ancestor class
Line
Attributes:start positionend position
Methods:draw
Coloured Line
Attributes:colour
Methods:setColour
Class ColouredLine: private Line{….};
main(){ColouredLine myLine;// myLine.draw();}
Object of privately derivedclass can’t access method
of base class
18
private/public/protected attributes
Now a quick comparison between public, private and protected attributes..
19
C++ Syntax: private attributes
We have a privately definedattribute x in the base class
20
C++ Syntax: private attributes
Here we have a method in the derivedclass (getIfYEqX) that needs to access
an attribute (x) declared in the base class
21
C++ Syntax: private attributes
Because ‘x’ is declared as private in thebase class, the derived class is not allowed
to access it directly so we get an errorand the code won’t compile
22
C++ Syntax: public attributes
If we change the attribute to be public thenthe method in the derived class can access it
but...
23
C++ Syntax: public attributes
Doing this goes against the idea ofencapsulation and data hiding
users of the class can access theattributes directly which is a bad
idea usually!
24
C++ Syntax: protected attributes
If we change the attribute to be protected
then the method in the derived class can
access the attribute in the base class..
25
C++ Syntax: protected attributes
And the notion of encapsulation anddata hiding is preserved becauseusers of the class aren’t allowedto access the protected attribute
directly
26
C++ Syntax: the ‘protected’ keyword
So in summary...Protected attributes share some features of public and some of private:
Derived classes can access the protected attributes of their ancestor classes (as if they were publicly defined)
but external users of the class can’t access the protected attributes(as if they were privately defined)
27
C++ Syntax: inheriting constructors
A derived class always inherits the constructor of the base class. The base class constructor is called first.
If the base class constructor takes no parameters then the inheritance is implicit - you don’t need to do anything!
If the base class constructor takes parameters then each derived class needs to declare a constructor with the same parameters. You can pass the arguments given to the derived class constructor to the constructor for the base class
28
C++ Syntax: inheriting constructors
Class Customer{Customer (char * name_in);…}
Class AccountCustomer:public Customer{AccountCustomer(char * name_in);..}
Base class declares aconstructor that takes
a char pointer parameter
Derived class declares aconstructor that takes the
same char pointer parameter
29
C++ Syntax: inheriting constructors
AccountCustomer: AccountCustomer(char * name_in):
Customer (name_in){//main body of constructor..}
In the implementation of theconstructor for the derived class,
the parameter passed to thederived class constructor is
passed down to the base class constructor. Note use of the colon (:) syntax once again
30
C++ Syntax: inheriting constructors
class creature{private:
int yearOfBirth;public:
creature(int YOB);int getYearOfBirth();
};
int main(){
creature myCreature(1985);cout << "my creature was born in " << myCreature.getYearOfBirth() <<endl;return 0;
}
This class has a constructorthat takes an integer argument.
When instantiating an object ofthis class you pass a parameter
to the constructor.
31
C++ Syntax: inheriting constructors
class dog:public creature{public:
void bark();};
int main(){
creature myCreature(1985);dog myDog(1985);
cout << "my creature was born in " << myCreature.getYearOfBirth() <<endl;
return 0;}
At the moment we can’t do this:there is no constructor for thedog class that takes an integer
argument
Dog class derived fromcreature class
32
C++ Syntax: inheriting constructors
class dog:public creature{public:
dog(int YOB);void bark();
};
//implementation for dog constructordog::dog(int YOB):creature(YOB){//other constructor stuff goes here}
Now we have defined aconstructor that does take
an integer argument
The argument sent to thedog constructor gets sent
to the creature constructorso the YearOfBirth attributeof the base class gets set
properly
33
C++ Syntax: inheriting constructors
class dog:public creature{public:
dog(int YOB);void bark();
};
int main(){
creature myCreature(1985);dog myDog(1985);
cout << "my creature was born in " << myCreature.getYearOfBirth() <<endl;cout << "my dog was born in " << myDog.getYearOfBirth() <<endl;return 0;
}
Now we do have anappropriate constructorfor the dog class whichcorrectly initialises the
attributes defined in thebase class
34
C++ Syntax: inheriting destructors
A derived class always inherits the destructor of the base class. The derived class destructor is called first. This is the reverse of the sequence for constructors
Because destructors never take an argument there is no issue with inheritance of destructor parameters.
35
This week’s new topic
Associationslinks between objects
Aggregationsobjects composed wholly or partly of
others
36
Associations
Up to now we have made single objects and called their methods from the main() function.
In practice it is likely that we will have many objects that will need to communicate with each other..
37
Types of associations
Associations can take many forms one to one one to many many to many bidirectional unidirectional
38
Types of associations
Associations can take many forms one to one
one object of a class has a link to one other object of a class
one to many many to many bidirectional unidirectional
39
Types of associations
Associations can take many forms one to one one to many
one object of a class has many links with objects of a particular class
many to many bidirectional unidirectional
40
Types of associations
Associations can take many forms one to one one to many many to many
many objects of one class have links with many objects of a particular class
bidirectional unidirectional
41
Types of associations
Associations can take many forms one to one one to many many to many bidirectional
messages can be sent in both directions
unidirectional
42
Types of associations
Associations can take many forms one to one one to many many to many bidirectional unidirectional
messages only need to be sent in one direction. One object is the ‘actor’ - acts upon anotherthe other is a server - it is only acted upon. [Booch,1994]
43
Aggregation
AggregationsUp to now we have made classes
that use simple data types for their attributes - (int, float, char etc)
Aggregations use objects of other classes to define their state
44
Terms used to describe aggregation
Aggregation Composition Part-Whole A part of (APO) Has-a Containment
45
Aggregation
Aggregation
46
Composition vs Aggregation
Composition Implies that the internal objects are not seen from the outside.
Aggregation implies that some objects have some visibility or existence outside of the hierarchy
47
Containment
Containmenta composition hierarchy defines how an object is composed
of other objects in a fixed relationship. Aggregate object cannot exist without its components.
Eg a car and its engine have a containment relationship
A Containeran object of a container class which is able to contain other
objects. Its existence is independent of whether it actually contains anything. Contained objects will probably be dynamic and vary over time.
Eg a car boot is a container which is able to contain some or no objects
48
Aggregations
Aggregations can be fixed
- like in composition - the number and identity of contained objects is always the same
variable - as with a container object - the number of contained
objects may vary at runtime
recursivemay contain components of its own type
49
Fixed Aggregation in C++
Fixed aggregation - declare attributes as objects rather than standard data types
class car{private:
engine myEngine;light left_headlight;light right_headlight;
};
Class attributes nowinclude objects of
other classes
50
Fixed Aggregation in C++
aggregated class can then call methods of the component objects
voidcar::LightsOn(){left_headlight.switchOn();right_headlight.switchOn();}
Car class methodscan now call methods
of the contained objects
51
Fixed Aggregation with parameters
What if the contained objects require parameters for their construction?
class wheel
{
private:
int diameter;
public:
wheel(diameter_in);
int getDiameter();
};
Constructor for wheelclass takes an integer
argument to defineits diameter
52
Fixed Aggregation with parameters
What if the contained objects require parameters for their construction?
class car
{
private:
wheel l_front, r_front, l_back, r_back;
engine theEngine;
public:
car (int diameter_in,int enginecc_in);
};
Constructor for carclass takes enough
parameters to constructall the constituent
objects
53
Fixed Aggregation with parameters
What if the contained objects require parameters for their construction?
car::car (int diameter_in,int enginecc_in):l_front(diameter_in),r_front(diameter_in),l_back(diameter_in),r_back(diameter_in),theEngine(enginecc_in){//rest of constructor code goes here}
Note use of colon(:) operatorto pass parameters sent toconstructor of aggregatedobject to the constructorsof the constituent objects
54
Variable Aggregation in C++
Variable aggregation - declare attributes as object pointers rather than standard data types. Pointers can be set to NULL to represent no object
class car{private:
person * theDriver = NULL;..};
55
Variable Aggregation in C++
Variable aggregation - declare attributes as object pointers rather than standard data types. Pointers can be set to NULL to represent no object
class car{private:
person * theDriver = NULL;..};
Class attributes nowinclude pointers to
objects of other classes
56
Variable Aggregation in C++
car::addDriver(){theDriver=new person();}
We could have a methodwhich instantiates an object
of the contained classand allocates it to the
pointer like this..
57
Variable Aggregation in C++
car::addDriver(){theDriver=new person();}
car::removeDriver(){delete the Driver;theDriver=NULL;}
..and deletes it like this
58
Variable Aggregation in C++
However, some objects in an aggregation may have a lifetime outside of the contained object. In this case a pointer to the previously existing object needs to be passed to the containing object
car::addDriver(person * driver_in){theDriver=driver_in;}
59
Variable Aggregation in C++
However, some objects in an aggregation may have a lifetime outside of the contained object. In this case a pointer to the previously existing object needs to be passed to the containing object
car::addDriver(person * driver_in){theDriver=driver_in;}
A pointer to a previouslyexisting object is now
available to the aggregatedobject
60
Variable Aggregation in C++
Removing the object from the aggregation simply means setting the pointer to null. (the object continues to exist in its own right but not as part of the aggregation)
car::removeDriver(){theDriver=NULL;}
61
Variable Aggregation in C++
Removing the object from the aggregation simply means setting the pointer to null. (the object continues to exist in its own right but not as part of the aggregation)
car::removeDriver(){theDriver=NULL;}
The car object wouldnow have no driver pointerbut the driver person object
would continue to exist outsideof the car
62
Implementing associations in C++
forms of Associations one to one one to many many to many bidirectional unidirectional
63
Implementing associations in C++
forms of Associations one to one unidirectional
eg a light switch and a lightthe switch is an ‘actor’ - it acts upon
another object [Brooch]
the light is a server -it is told what to doswitch needs a pointer to the light object
to be able to control it
64
Implementing associations in C++
forms of Associations one to one unidirectional
main(){light * bigLight= new light();button * lightButton=new button(bigLight);..}
Create a dynamic light objectpass its pointer to the constructor
for the new button objectbutton object can now call methods
of the light object
65
Implementing associations in C++
forms of Associations one to one bidirectional
eg between two people objects who become ‘married’
two person objects of the same classeach object needs a pointer to the
other object (its ‘partner’)
66
Implementing associations in C++
forms of Associations one to one bidirectional
class person{private:
person * partner;..}
The person class nowcontains a pointer toanother object of theperson class. Initially
thiswill be set to NULL,
but when the persongets ‘married’ thepartner pointer will
point to another object of
the person class
67
Implementing associations in C++
forms of Associations one to one bidirectional
main(){person * Fred=new person();person * Wilma=new person();Fred.marry(Wilma);Wilma.marry(Fred);..}
68
Implementing associations in C++
forms of Associations one to one bidirectional
main(){person * Fred=new person();person * Wilma=new person();Fred.marry(Wilma);Wilma.marry(Fred);..}
We can create two dynamic person
objects and then call the ‘marry’ method
from each. This repetition is necessary
to ensure both partners know who they are married to!
69
Implementing associations in C++
forms of Associations one to one bidirectional
a method of establishing both ends of the bidirectional link simultaneously is to use the this keyword
All objects in C++ have a this pointer which points to themselves
70
Implementing associations in C++
forms of Associations one to one bidirectional
person::marry(person * partner_in){//establish one way linkpartner=partner_in;//now do the other waypartner->marry(this);..}
When the ‘marry’ method of one object
is called it automatically calls the ‘marry’ method of its
new spouse!
71
Implementing associations in C++
Need to avoid an infinite
recursive call here!
72
Implementing associations in C++
forms of Associations multiple associations
Maintain an array of pointers and an integer attribute to record the current number of objects referenced.
Car::addPassenger(person * passenger_in){if (numPassengers<5){passenger[numPassengers++]=passenger_in;
73
Implementing associations in C++
forms of Associations multiple associations
Maintain an array of pointers and an integer attribute to record the current number of objects referenced.
car::addPassenger(person * passenger_in){
if (numPassengers<5){passenger[numPassengers++]=passenger_in;}
..}
numPassengers is an integer attribute of the
car classIf the car is not full then add the new passenger
74
Implementing associations in C++
forms of Associations multiple associations
Maintain an array of pointers and an integer attribute to record the current number of objects referenced.
car::addPassenger(person * passenger_in){
if (numPassengers<5){passenger[numPassengers++]=passenger_in;}
..}
Here we use the postfix increment operator to
update the numPassengers variable
75
Summary
Associationslinks between objects
Aggregationsobjects composed wholly or partly of
others
76
Summary: associations
forms of Associations one to one one to many many to many bidirectional unidirectional
77
Summary: Aggregation
Composition Implies that the internal objects are not seen from the outside.
Aggregation implies that some objects have some visibility or existence outside of the hierarchy
78
Summary: Aggregation
Aggregations can be fixed
- like in composition - the number and identity of contained objects is always the same - use named automatic objects
variable - as with a container object - the number of contained
objects may vary at runtime - use pointers which can be NULL
recursivemay contain components of its own type