introduction to programming - bs.informatik.uni-siegen.de fileadrian kacso / r. wismu¨ller / t....

Post on 02-Sep-2019

7 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Adrian Kacso / R. Wismuller / T. KielmannBetriebssysteme / verteilte Systeme Introduction to Programming (1) i

Adrian Kacso, Univ. Siegenadriana.dkacsoa@duni-siegena.dde

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 = &sub;

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)

top related