introduction to programming - bs.informatik.uni-siegen.de fileadrian kacso / r. wismu¨ller / t....
TRANSCRIPT
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (1) i
Adrian Kacso, Univ. [email protected]
Tel.: 0271/740-3966, Office: H-B 8406
Stand: June 21, 2010
Introduction to ProgrammingSS 2010
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 255
Introduction to ProgrammingSS 2010
9 Inheritance and Polymorphism
9 Inheritance and Polymorphism ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 256
Contents:
➥ Inheritance
➥ Polymorphism
➥ Abstract classes
➥ Yet another example
9.1 Inheritance
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 257
Reminder: classes
➥ A class defines a new type:
➥ a collection of variables (data members , attributes )
➥ a set of related operations (methods , member functions )
➥ they define the interface to objects of the class
➥ i.e., the data members can (usually) be accessed only viathese methods
➥ An object is an instance (a variable) of a class
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 258
Often Classes are quite similar
➥ Assume we need classes for cats and dogs:
Cat Dogage age
Attributes weight weight
breed
eat() eat()
Methods Speak() Speak()
purr() wagTail()
➥ Why are these classes so similar?
➥ Because both cats and dogs are special kinds of mammals!
➥ the common attributes / methods are those of mammals
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 259
Refinement / specialization
Mammal
DogCatbreed
wagTail()purr()
eat()
weightage
Speak()
➥ Class Mammal defines thecommon attributes andmethods
➥ Cat and Dog are derivedfrom Mammal
➥ They inherit all attributesand methods of Mammal➥ they also can define
additional ones
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 260
Extending the hierarchy of animal classes ...
Animal
Mammal Fish
CatDog
ageweight
eat()
nurseBaby()spawn()
breed
wagTail()purr()
Speak()
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 261
Relations between classes
➥ Mammal inherits from Animal,and Dog inherits from Mammal
➥ A Dog is a Mammal which is an Animal
➥ Animal is a (direct) base class (or superclass ) of Mammal,Animal and Mammal are base classes (or superclasses ) of Dog
➥ Mammal is a derived class (or subclass ) of Animal,Dog and Mammal are derived classes (or subclasses ) of Animal
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 262
Uses of inheritance
➥ Conceptual Modelling:
➥ define a hierarchy of classes that represent the concepts of thedata➥ specialization / generalization, e.g., cats and dogs as
special kinds of mammals
➥ this mostly defines hierarchies of interfaces
➥ Code re-use:
➥ take a given class, and extend it by a little code to get what youneed
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 263
A Mammal class
class Mammal {
public:
Mammal();
~Mammal();
int getAge() const;
void setAge(int);
int getWeight() const;
void setWeight(int);
void Speak() const;
protected: // allow access by derived classesint itsAge;
int itsWeight;
};
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 264
Private vs. protected vs. public
Class members can be private, protected, or public:
➥ private members can be accessed only within methods of theclass itself
➥ protected members can be accessed from within methods of theclass itself, and of its derived classes
➥ public members can also be accessed from other classes (“codeoutside the class itself”)
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 265
A Cat class
class Cat : public Mammal {
public:
Cat();
~Cat();
void purr() const;
};
➥ public class inheritance means that the public members of thebase class are also public for the derived class
➥ (there is also private and protected inheritance, but we will notuse it in this course)
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 266
A Dog class
enum Breed {
YORKIE, DANDIE, SHETLAND, DOBERMAN, LABRADOR
};
class Dog : public Mammal {
public:
Dog();
Dog(Breed breed);
~Dog();
Breed getBreed() const;
void wagTail() const;
protected:
Breed itsBreed;
};
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 267
The interface of Dog (accumulated)
➥ The following methods can be called for a Dog object:
Inherited from Mammal Defined by Dog
int getAge() const; Dog();
void setAge(int); Dog(Breed breed);
int getWeight() const; ~Dog();
void setWeight(int); Breed getBreed() const;
void Speak() const; void wagTail() const;
➥ The constructor and destructor is not inherited !!
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 268
The data members of Dog (accumulated)
➥ A Dog object has the following data members:
Inherited from Mammal Defined by Dog
int itsAge; Breed itsBreed;
int itsWeight;
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 269
Constructors and destructors
➥ What happens when a Dog is created?
➥ first, the Mammal constructor is called➥ it initializes the data members inherited from Mammal
➥ then, the Dog constructor is called➥ it initializes the data members added by Dog
➥ And when a Dog is deleted?
➥ first, the Dog destructor is called,
➥ then, the Mammal destructor
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 270
Passing arguments to base constructors
➥ Assume we have the following constructors for Mammal:
Mammal();
Mammal(int age);
➥ And we want the following ones for Dog:
Dog();
Dog(int age, Breed breed);
Dog(int age, int weight, Breed breed);
➥ How to do this?
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 271
Passing arguments to base constructors ...
➥ The Mammal constructors could be implemented like this:
Mammal::Mammal()
: itsAge(1),
itsWeight(5)
{
}
Mammal::Mammal(int age)
: itsAge(age),
itsWeight(5)
{
}
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 272
Passing arguments to base constructors ...
Dog::Dog()
: Mammal(), // could be omitteditsBreed(YORKIE)
{}
Dog::Dog(int age, BREED breed)
: Mammal(age), // base class initializationitsBreed(breed)
{}
Dog::Dog(int age, int weight, BREED breed): Mammal(age),
itsBreed(breed)
{
itsWeight = weight; // cannot initialize itsWeight}
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 273
Overriding methods
➥ Implementation of the Speak method in Mammal:
void Mammal::Speak()
{
cout << "Mammal sound" << endl;
}
➥ Mammal m; m.Speak(); ⇒ Mammal sound
➥ Dog d; d.Speak(); ⇒ Mammal sound
➥ Dog inherits the implementation of Speak
➥ but shouldn’t a dog say “Woof”?
➥ Dog should implement the Speak method differently
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 274
Overriding methods ...
➥ This can be done by overriding the method:
class Dog : public Mammal {
public:
...
void Speak() const; // redefine the method// in class Dog
};
void Dog::Speak() const // and provide a new{ // implementation
cout << "Woof!" << endl;
}
➥ Dog d; d.Speak(); ⇒ Woof!
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 275
Overriding vs. overloading
➥ Overloading➥ define multiple methods with the same name, but different
signature
➥ Overriding➥ define a method in a derived class with the same name and
signature as in the base class
➥ Caution: overriding means hiding!
➥ if you override one of many, overloaded methods (with thesame name), you hide all of them!
9.1 Inheritance ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 276
Hiding, calling base methods
void Mammal::Move(int distance) {...}
void Mammal::Move(int distance, int angle) {...}
void Dog::Move(int distance) {...}
➥ Now, with Dog d; you can not call d.Move(2,4) anymore
➥ But, you can call d.Mammal::Move(2,4)
➥ And even d.Mammal::Move(2), which calls Mammal’simplementation of Move(int distance)
9.2 Polymorphism
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 277
➥ Often we want an object to do something, without knowing theexact class of the object
➥ E.g., if the Cat class implements
void Cat::Speak() const {
cout << "Meow!" << endl;
}
can we do something like
Mammal *myPets[3]; int i;
myPets[0] = new Dog(DOBERMAN);
myPets[1] = new Cat();
myPets[2] = new Dog(LABRADOR);
cin >> i; myPets[i]->Speak(); // ==> Woof! or Meow!
9.2 Polymorphism ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 278
Pointers, references and inheritance
➥ If Sub is a subclass of Super, then the following assignments areallowed:
Sub sub;
Super *p = ⊂
Super &r = sub;
➥ I.e., a superclass pointer (reference) can also point (refer) to anobject of a subclass
➥ but not the other way round!
➥ Quiz: what happens in this case?
Sub sub; Super super;
super = sub;
9.2 Polymorphism ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 279
Virtual methods
➥ In C++, if you want the polymorphism to work, the base classmust declare the methods in question as being virtual!
class Mammal {
public:
...
virtual void Speak() const;
...
};
➥ Otherwise, in our example, you would just get Mammal sound
➥ i.e., the method of class Mammal is invoked
9.2 Polymorphism ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 280
How does it work?
itsAgeitsWeight
itsBreed
Dog object
Mammal part
in memory:A Dog object
➥ An object of a derived class consists of
➥ data members of the base class
➥ additional data members of the derived class
9.2 Polymorphism ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 281
How does it work? ...
(seen by d)
Dog *d itsAgeitsWeight
itsBreed
Dog object
Mammal part
in memory:A Dog object
➥ A derived class pointer “sees” everything
9.2 Polymorphism ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 282
How does it work? ...
(seen by m)
Mammal *m
(seen by d)
Dog *d itsAgeitsWeight
itsBreed
Dog object
Mammal part
in memory:A Dog object
➥ A base class pointer “sees” just the base class part at thebeginning
9.2 Polymorphism ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 283
How does it work? ...
v−table
Speak()
Move()...
Mammal::Move(...) { ...}
Dog::Speak() { cout << "Woof!"...}
itsAgeitsWeight
itsBreed
vptr
Mammal *m
Dog *d
in memory:A Dog object
➥ The object contains a pointer to a virtual method table
➥ this table has an entry for each virtual method, which points tothe proper implementation
➥ Thus, each object “knows” its virtual methods
9.2 Polymorphism ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 284
How does it work? (now with a Cat object)
v−table
Speak()
Move()...
}
Mammal::Move(...) { ...}
Cat::Speak() { cout << "Meow! ...
itsAgeitsWeight
vptr
Mammal *m
Cat *c
in memory:A Cat object
➥ In a Cat object’s virtual method table, the entry for Speak() pointsto Cat::Speak()
➥ Thus, m->Speak() prints: Moew!
9.2 Polymorphism ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 285
How does it work? (now with a Mammal object)
v−table
Speak()
Move()...
}
Mammal::Move(...) { ...}
Mammal::Speak() { cout << "Mamm ...
itsAgeitsWeight
vptr
Mammal *min memory:A Mammal object
➥ In a Mammal object’s virtual method table, the entry for Speak()points to Mammal::Speak()
➥ Thus, m->Speak() prints: Mammal sound
9.2 Polymorphism ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 286
Virtual destructors
➥ When an object is destroyed, we always want to call the destructorof the object’s actual class
➥ e.g., call ~Dog(), even with a pointer to Mammal
➥ In principle, destructors should always be declared as virtual
➥ but virtual makes objects larger and method calls slower
➥ Rule of thumb :
➥ if a class contains a virtual method, the destructor also shouldbe virtual
(assumption: in this case, you refer to objects via a base classpointer or reference)
9.3 Abstract Classes
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 287
Reminder: the drawing example
➥ Remember the classes of our drawing program example:
Point Line Rectangle
draw()move()rotate()getX()getY()
rotate()move()draw()
rotate()move()draw()
➥ Ideally, we would like to use the methods draw(), move(), androtate() in a polymorphic way, e.g.:
drawingElements[i]->draw();
9.3 Abstract Classes ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 288
A class hierarchy for the drawing example
Point Rectangle
DrawingElement
Line
getX()getY()
draw()move()rotate()
➥ But, implementing draw(), move(), and rotate() in the baseclass doesn’t really make sense!
9.3 Abstract Classes ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 289
The animal hierarchy revisited
Animal
Mammal Fish
CatDog
ageweight
eat()
nurseBaby()spawn()
breed
wagTail()purr()
Speak()
➥ Animal and Mammal provideuseful interfaces
➥ But implementing themethods only makes sensefor the bottommost classes➥ think e.g. of this artificial
“Mammal sound” inMammal::Speak()
➥ Animal or Mammal objectsalso don’t make too muchsense
9.3 Abstract Classes ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 290
Pure virtual methods
➥ Instead of providing an interface and its implementation, a baseclass also can provide only the interface:
class Mammal {
public:
Mammal();virtual ~Mammal();
...virtual void Speak() const = 0; // pure virtual...
};
➥ That is, we leave the implementation to the derived classes:
void Dog::Speak() const {
cout << "Woof!\n";}
9.3 Abstract Classes ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 291
Abstract classes
➥ In C++, a class is abstract , if it has at least one pure virtualmethod
➥ abstract C++ classes may also implement some methods
➥ An abstract class can not be instantiated
➥ you cannot create an object of an abstract class
➥ But (of course) polymorphism still works
➥ if AC is an abstract class,you can still use pointers (or references ) to AC
to point to objects of (non-abstract) subclasses of AC
➥ (In Java, interfaces serve a similar purpose)
9.3 Abstract Classes ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 292
Hierarchies of abstract / concrete classes
➥ We can define Animal and Mammal as abstract classes
➥ they now simply provide common interfaces for all theirsubclasses
➥ If we derive Dog and Cat from Mammal, we make these classesconcrete ,so we can have Dog objects that implement the Mammal interface
9.3 Abstract Classes ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 293
The abstract / concrete hierarchy of animals
(defineinterfaces)
weight
eat()
Mammal Fish
spawn()Speak()
age
nurseBaby()
Cat Dog
breed
wagTail()purr()
Animal
ConcreteClasses
(provideimplementations)
ClassesAbstract
9.4 Yet Another Example
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 294
A hierarchy of graphics elements
➥ From a previous exam:
Define an abstract class Element for graphics elements.
The abstract class shall have a method circumference thatreturns the circumference of the object as a double value.
9.4 Yet Another Example ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 295
Class Element
class Element {
public:
virtual ~Element() {}
virtual double circumference() const = 0;
};
Notes :
➥ No need to declare a constructor
➥ the compiler will create an empty one for us
➥ We are using a short form with ~Element(): you can also define amethod’s body inside the class declaration
➥ not recommended for real programming!
9.4 Yet Another Example ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 296
Derive real classes
➥ Implement three classes of graphics elements which are derivedfrom Element:
1. Circle, defined via its radius r.
2. Rectangle, defined via the lengths of its sides a and b.
3. Square, derived from Rectangle, using a = b.
For each class, you need to implement a constructor, the methodCircumference, and the data members.
➥ (Remark: In general, deriving a square class from a rectangleclass is a questionable approach: although each square is arectangle, not every operation on a rectangle is allowed on asquare, e.g., “set the length of one side”)
9.4 Yet Another Example ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 297
Class Circle
class Circle : public Element {
public:
Circle(double radius) : itsRadius(radius) {}
double circumference() const {
return 2 * PI * itsRadius;
}
private:
double itsRadius;
};
9.4 Yet Another Example ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 298
Class Rectangle
class Rectangle : public Element {
public:
Rectangle(double a, double b)
: itsA(a), itsB(b) {}
double circumference() const {
return 2 * (itsA + itsB);
}
private:
double itsA, itsB;
};
9.4 Yet Another Example ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 299
Class Square
class Square : public Rectangle {
public:
Square(double a) : Rectangle(a,a) {}
};
9.4 Yet Another Example ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 300
Use the Element interface
➥ Implement a function:
double sum(Element const *array[],
unsigned int len)
that computes the sum of the circumferences of the Element
objects in the array.
len gives the length of the array.
9.4 Yet Another Example ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 301
Function sum()
double sum(Element const *array[],
unsigned int len)
{
double retval = 0.0;
//unsigned int i;
for ( unsigned int i=0; i < len; i++) {
retval += array[i]->circumference();
}
return retval;
}
9.5 Summary
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 302
Inheritance
Mammal
DogCatbreed
wagTail()purr()
eat()
weightage
Speak()
➥ Class Mammal defines thecommon attributes andmethods
➥ Cat and Dog are derivedfrom Mammal
➥ They inherit all attributesand methods of Mammal➥ they also can define
additional ones
9.5 Summary ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 303
A Cat class derived from Mammal
class Mammal {
public:
Mammal(); ~Mammal();
int getAge() const;
...
protected: // allow access by derived classesint itsAge;
int itsWeight;
};
class Cat : public Mammal { // public members remain publicpublic:
Cat(); ~Cat();
void purr() const;
};
9.5 Summary ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 304
Polymorphism
➥ Often we want an object to do something, without knowing theexact class of the object
➥ E.g., we can write
Mammal *myPets[3]; int i;
myPets[0] = new Dog(DOBERMAN);
myPets[1] = new Cat();
myPets[2] = new Dog(LAB);
cin >> i; myPets[i]->Speak(); // ==> Woof! or Meow!
➥ Caveat : This only works if Mammal declares the Speak-Method asvirtual!
9.5 Summary ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 305
How do virtual methods work?
v−table
Speak()
Move()...
Mammal::Move(...) { ...}
Dog::Speak() { cout << "Woof!"...}
itsAgeitsWeight
itsBreed
vptr
Mammal *m
Dog *d
in memory:A Dog object
➥ The object contains a pointer to a virtual method table
➥ This table has an entry for each virtual method, which points tothe proper implementation
➥ Thus, each object “knows” its virtual methods
9.5 Summary ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 306
Pure virtual methods
➥ Instead of providing an interface and its implementation, a baseclass also can provide only the interface:
class Mammal {
public:
Mammal();virtual ~Mammal();
...virtual void Speak() const = 0; // pure virtual...
};
➥ That is, we leave the implementation to the derived classes:
void Dog::Speak() const {
cout << "Woof!\n";}
9.5 Summary ...
Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (2) 307
Reminder: abstract classes
➥ In C++, a class is abstract , if it has at least one pure virtualmethod
➥ abstract C++ classes may also implement some methods
➥ An abstract class can not be instantiated
➥ you cannot create an object of an abstract class
➥ But (of course) polymorphism still works
➥ if AC is an abstract class,you can still use pointers (or references ) to AC
to point to objects of (non-abstract) subclasses of AC
➥ (In Java, interfaces serve a similar purpose)