68
Inheritance and Role Modelling Stephen P Levitt School of Electrical and Information Engineering University of the Witwatersrand 2019

Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

  • Upload
    others

  • View
    10

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Inheritance and Role Modelling

Stephen P Levitt

School of Electrical and Information EngineeringUniversity of the Witwatersrand

2019

Page 2: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Inheritance and Role Modelling in Three Parts

Part I: Key ConceptsPart II: The MechanicsPart III: ModellingSummary

Inheritance and Role Modelling 1 / 66

Page 3: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Part I

Inheritance: Key Concepts

Inheritance and Role Modelling : : 2 / 66

Page 4: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Outline of Part I — Inheritance: Key Concepts

1 Introduction

2 A Tale of Two Uses of InheritanceImplementation InheritanceInterface Inheritance / Role Modelling

3 Polymorphism

Inheritance and Role Modelling : : 3 / 66

Page 5: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Inheritance

Source: Object-Oriented Analysis and Design, 2nd ed., G. Booch, 1994

Inheritance and Role Modelling : Introduction 4 / 66

Page 6: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Inheritance

Inheritance is a key part of object-oriented programmingAnalogous with biological inheritanceCaptures shared characteristics or commonalityModels an “is–a” relationship.Terminology:

Base/DerivedParent/ChildSuperclass/Subclass

Inheritance and Role Modelling : Introduction 5 / 66

Page 7: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Implementation Inheritance I

class Rectangle{public:Rectangle(int b, int h): base_{b}, height_{h} // constructor{}

int base() const { return base_;}int perimeter() const { return ((base_ + height_)*2); }

//...

private:int base_;int height_;

};

Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : Implementation Inheritance 6 / 66

Page 8: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Implementation Inheritance II

enum Colour {RED, GREEN, BLUE};

class ColourRect : public Rectangle{public:

ColourRect (int b, int h, Col c):Rectangle{b, h},colour_{c}{}

void colour (Colour c) { colour_ = c;}Colour colour() { return colour_; }

private:Colour colour_;

};

Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : Implementation Inheritance 7 / 66

Page 9: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Using Rectangle and Coloured Rectangle

Rectangle rect{10, 20};// uses rectangle's functionscout << rect.perimeter();cout << rect.base();

ColourRect colrect{10, 20, GREEN};// ColourRect inherits Rectangle's functionscout << colrect.perimeter();cout << colrect.base();

// only defined for ColourRectcout << colrect.colour();

Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : Implementation Inheritance 8 / 66

Page 10: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

UML Diagram — Reuse Within the Hierarchy

+ base(int): void + base(): int +height(int): void +height(): int +perimeter(): int +area(): int +scale(int): void

_base: int _height: int

Rectangle

+colour(): Colour +colour(Colour): void

_colour: Colour

ColourRect

Reuse of perimeter, area etc occurs here - within the inheritance hierarchy

Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : Implementation Inheritance 9 / 66

Page 11: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Avoid Using Implementation Inheritance!

Using public inheritance primarily for the purpose of reusing the base classimplementation often leads to:

difficult-to-maintain code because of tight couplingunnatural designs, see “Refused Bequest”unnecessary compile-time dependencies, see pure interfaces

Better (less highly coupled, more flexible) alternatives exist, including composition.

Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : Implementation Inheritance 10 / 66

Page 12: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Interface Inheritance / Modelling a Role in the System

This system has things that are Drivable

class Drivable{public:

// none of these functions have an implementationvirtual void start() = 0;virtual void rotateSteeringWheel(int degrees) = 0;virtual void changeGearUp() = 0;virtual void changeGearDown() = 0;virtual void stop() = 0;

};

Classes which are derived from Drivable inherit a contract.

Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : Interface Inheritance / Role Modelling 11 / 66

Page 13: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Interface Inheritance / Role Modelling

Source: Object-Oriented Analysis and Design, 2nd ed., G. Booch, 1994

Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : Interface Inheritance / Role Modelling 12 / 66

Page 14: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Programming to Drivable’s Interface

void takeMeHome(Drivable& drivable){drivable.start();drivable.changeGearUp();drivable.rotateSteeringWheel(90); // turn rightdrivable.changeGearUp(); // increase speeddrivable.rotateSteeringWheel(90); // turn right again

// ...

drivable.stop(); // at homereturn;

}

Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : Interface Inheritance / Role Modelling 13 / 66

Page 15: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Classes Implementing Drivable’s Interface / Fulfilling the Role

class VolkswagenBeetle: public Drivable{public: // must override all the virtual functions

virtual void start() override{ // start the Beetle }// ...

};

class Jeep: public Drivable{public: // must override all the virtual functions

virtual void start() override{ // start the Jeep }// ...

};

Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : Interface Inheritance / Role Modelling 14 / 66

Page 16: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Client Code Using takeMeHome

// client code

VolkswagenBeetle beetle;takeMeHome(beetle);

// or

Jeep jeep;takeMeHome(jeep);

The takeMeHome function has no knowledge of the derived type that it is using.

If we do not make use of the Drivable interface we are forced to write a new versionof this function for each and every Drivable object.

Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : Interface Inheritance / Role Modelling 15 / 66

Page 17: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Using Inheritance Appropriately I

“ When using inheritance, ask yourself whether your derived class is substi-tutable in place of the base class. If the answer is no, then ask yourselfwhy you are using inheritance. If the answer is to reuse code in thebase class when developing your new class, then you should probably usecomposition instead.”— Subramaniam and Hunt, 2006, in Practices of an Agile Developer

Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : Interface Inheritance / Role Modelling 16 / 66

Page 18: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Using Inheritance Appropriately II

“ Inherit, not to reuse code that exists in the base class, but to be reusedby existing code that already uses base objects polymorphically.”— Sutter and Alexandrescu, 2005, in C++ Coding Standards

Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : Interface Inheritance / Role Modelling 17 / 66

Page 19: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

UML Diagram — Reuse Outside the Hierarchy

+start():void

+rotateSteeringWheel(int degrees):void

+changeGearUp(): void

+changeGearDown(): void

+stop() : void

Drivable

takeMeHome

VolkswagenBeetle Jeep

One takeMeHome function is used to

drive many different types of vehicles –

reuse is occurring outside the

inheritance hierarchy

Inherit from Drivable to be reused by the

takeMeHome function

takeMeHome depends

on the interface offered

by Drivable

Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : Interface Inheritance / Role Modelling 18 / 66

Page 20: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Polymorphism — Definition

Polymorphism allows a base type to express some sort of contract/interface, and forderived types to implement that interface in different ways, each according to theirown purpose. Code using the base type interface should not have to care about whichimplementation is involved, only that the contract will be obeyed.

Alternatively: Polymorphism allows multiple implementations to respond to the samemessage without the message sender needing to know or care which implementation ishandling the message.

[based on answers by Jon Skeet and Doug Knesek, stackoverflow.com, 2009]

Inheritance and Role Modelling : Polymorphism 19 / 66

Page 21: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Part II

The Mechanics of Inheritance

Inheritance and Role Modelling : : 20 / 66

Page 22: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Outline of Part II — The Mechanics of Inheritance

4 virtual Functions and Late Binding

5 Abstract Base Classes

6 Default and Mandatory Implementations for Derived Types

7 Protected Data Members and Member Functions

8 Derived Class Constructors

9 Inheritance versus Composition

10 Derived Class Destructors

Inheritance and Role Modelling : : 21 / 66

Page 23: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

virtual functions and Late/Dynamic Binding

Are the C++ mechanisms (language constructs) used for achieving polymorphismOrdinary (non-virtual) functions are bound at compile time (static or earlybinding)virtual functions are bound at run time using a virtual table (dynamic or latebinding)virtual functions bind to the type of the object being pointed to or referenced —not to the type of the pointer or referenceFor virtual functions to be overridden they must have identical signatures(overloaded functions must have different signatures)A function need only be declared virtual once in the base class but it is clearerto redeclare it virtual wherever it is overridden

Inheritance and Role Modelling : virtual Functions and Late Binding 22 / 66

Page 24: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Making Use of Polymorphism and Late Binding

Late binding only occurs in the following two instances:1 A reference to a base class is assigned to a derived class object — this often

occurs within the context of function call:void takeMeHome( Drivable& drivable);Jeep jeep;

takeMeHome(jeep); // Jeep's functions are called

2 A pointer, or smart pointer, which is declared of the base class type, is pointed toan object of the derived class:shared_ptr< Drivable> car_ptr = make_shared<Jeep>();

car_ptr->rotateSteeringWheel(45); // Jeep's function is called

Inheritance and Role Modelling : virtual Functions and Late Binding 23 / 66

Page 25: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Polymorphism and Pointers

Write a function called AnimalChorus which takes in a vector of animals and makeseach of them speak in turn. Write a main function which uses AnimalChorus.

class Animal{public:

virtual void Speak() const = 0;};

class Dog: public Animal{public:

virtual void Speak() const override { cout << "Woof"; }};

class Cat: public Animal// ...

Inheritance and Role Modelling : virtual Functions and Late Binding 24 / 66

Page 26: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Abstract Base Classes (ABCs)

A pure virtual function has no implementation, for example:class WritingInstrument{public:virtual void draw(int x_start, int y_start, int x_end, int y_end) = 0;

};

You cannot directly create an object from a class which has a pure virtual memberfunction — you can provide a constructorClasses containing a pure virtual function are known as abstract base classesAll derived classes are forced to override the virtual function

Inheritance and Role Modelling : Abstract Base Classes 25 / 66

Page 27: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Providing Default and Mandatory Implementations for Derived Types I

class Shape {public:// pure virtual functionvirtual void draw() const = 0;

// ordinary virtual function// provides default implementationvirtual void error(const string& msg);

// non-virtual function// provides mandatory implementationint objectID() const;

}

Inheritance and Role Modelling : Default and Mandatory Implementations for Derived Types 26 / 66

Page 28: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Providing Default and Mandatory Implementations for Derived Types II

All member functions are inherited. If a function applies to a class, it should alsoapply to its subclasses.Pure virtual function: derived classes inherit a function interface (signature) onlyOrdinary virtual function: derived classes inherit a function interface as well as adefault implementationNon-virtual function: derived classes inherit a function interface as well as amandatory implementation which is invariant over specialisation

Inheritance and Role Modelling : Default and Mandatory Implementations for Derived Types 27 / 66

Page 29: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Use the virtual keyword appropriately

“ Say what you mean; understand what you’re saying.”— Scott Meyer, 2005, in Effective C++

Inheritance and Role Modelling : Default and Mandatory Implementations for Derived Types 28 / 66

Page 30: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Protected Data Members and Member FunctionsA derived class is allowed direct access to the protected data members of its baseclass.

class LibraryItem {public:

// must maintain invariants related to the number of copiesvoid returnItem();void borrowItem()

protected:unsigned int total_copies_;unsigned int available_copies_;

};

class Book: public LibraryItem {// has direct access to total_copies_ and available_copies_

};

Inheritance and Role Modelling : Protected Data Members and Member Functions 29 / 66

Page 31: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Protected Data Members and Member Functions cont.

Protected Data MembersHave the same drawback as public data members — lack of access controlImpossible for the class which owns the protected data to preserve any invariants

Protected Member FunctionsAre inherited but do not form part of the derived class’s public interface

Make data private and if derived classes require access provide public or protectedaccess functions

Inheritance and Role Modelling : Protected Data Members and Member Functions 30 / 66

Page 32: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Derived Class Constructors

Derived class objects are built on top of base class objects.Base class constructor is always called — either explicitly or implicitlyThe base class constructor is always called prior to the derived class constructor(in the order in which inheritance is specified in the derived class definition).

Inheritance and Role Modelling : Derived Class Constructors 31 / 66

Page 33: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Inheritance versus Composition: Class Constructors

List the private data members and write out the constructors for the two cases givenbelow.Class ColourRect is derived from class Rectangle - this is an inheritancerelationship.class ColourRect : public Rectangle{

// ?};

Class ColourRect2 has a Rectangle data member - this is a compositionrelationship.class ColourRect2{

// ?};

Inheritance and Role Modelling : Inheritance versus Composition 32 / 66

Page 34: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Inheritance

Source: Object-Oriented Analysis and Design, 2nd ed., G. Booch, 1994

Inheritance and Role Modelling : Inheritance versus Composition 33 / 66

Page 35: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Composition

Source: Object-Oriented Analysis and Design, 2nd ed., G. Booch, 1994

Inheritance and Role Modelling : Inheritance versus Composition 34 / 66

Page 36: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Derived Class Destructors

Destructors are called in the reverse order to constructorsDerived classes may require their own destructors in order to operate correctlyIf a base class has one or more virtual functions then we intend using usingderived classes via a pointer or reference of the base class type (polymorphism)Make the base class destructor virtual so that the appropriate derived classdestructor is called

Inheritance and Role Modelling : Derived Class Destructors 35 / 66

Page 37: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Destructor Example

class Shape {public:virtual void draw() const = 0;

// virtual destructor, defaults to doing nothingvirtual ~Shape() {}

}

class Circle : public Shape {public:Circle(unsigned int radius){/* allocate memory for Circle */ }

virtual ~Circle() // virtual destructor{/* free Circle's memory */}

}

Inheritance and Role Modelling : Derived Class Destructors 36 / 66

Page 38: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Destructor Example cont.

// in main

// prefer smart pointers - used here for illustrative purposesShape* shape_ptr = new Circle{10};

// This must call Circle's destructor otherwise a memory leak occurs.// For this to work, Shape's destructor must be declared virtual.delete shape_ptr;

Inheritance and Role Modelling : Derived Class Destructors 37 / 66

Page 39: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Part III

Modelling

Inheritance and Role Modelling : : 38 / 66

Page 40: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Outline of Part III — Modelling with Inheritance

11 Role ModellingFinding a Role to ModelModelling More Than One Role

12 Modelling DilemmasThe Liskov Substitution PrincipleRefused BequestModelling Roles Which Include Implementation DetailsExploding Class Hierarchies

Inheritance and Role Modelling : : 39 / 66

Page 41: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Finding a Common Role

1 class HouseFly {2 public:3 void FlyAroundYourHead() {}4 void LandOnThings() {}5 };6

7 class Telemarketer {8 public:9 void CallDuringDinner() {}10 void ContinueTalkingWhenYouSayNo() {}11 };

Inheritance and Role Modelling : Role Modelling : Finding a Role to Model 40 / 66

Page 42: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Finding a Common Role II

Both house flys and telemarketers are annoying

1 class Pest {2 public:3 virtual void BeAnnoying() = 0;4 };

Inheritance and Role Modelling : Role Modelling : Finding a Role to Model 41 / 66

Page 43: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Finding a Common Role III

1 class HouseFly: public Pest {2 public:3 void FlyAroundYourHead() {}4 void LandOnThings() {}5

6 virtual void BeAnnoying() override {7 FlyAroundYourHead();8 LandOnThings();9 }10 };

Inheritance and Role Modelling : Role Modelling : Finding a Role to Model 42 / 66

Page 44: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Finding a Common Role IV

1 class Telemarketer: public Pest {2 public:3 void CallDuringDinner() {};4 void ContinueTalkingWhenYouSayNo() {};5

6 virtual void BeAnnoying() override {7 CallDuringDinner();8 ContinueTalkingWhenYouSayNo();9 }10 };

Inheritance and Role Modelling : Role Modelling : Finding a Role to Model 43 / 66

Page 45: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Finding a Common Role V

1 void ServeDinner(const vector<shared_ptr<Pest>>& pests) {2 // when people are eating, annoy them3 for (auto pest: pests) pest->BeAnnoying();4 }5

6 int main()7 {8 auto pests =

vector<shared_ptr<Pest>>{make_shared<HouseFly>(),make_shared<Telemarketer>()};

9

10 ServeDinner(pests);11 }

Inheritance and Role Modelling : Role Modelling : Finding a Role to Model 44 / 66

Page 46: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Modelling Multiple Roles: A “Rollable” Role

Consider the concept of Rollable

class Rollable{public:virtual void roll() = 0;

};

Wheels can roll:

class Wheel : public Rollable { ... };

Inheritance and Role Modelling : Role Modelling : Modelling More Than One Role 45 / 66

Page 47: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Fulfilling More Than One RoleA Circle is both a Shape and Rollable:

1 // multiple inheritance of pure abstract classes2 class Circle: public Shape, public Rollable3 {4 public:5 virtual void draw() const override; // from Shape6 virtual void rotate(int deg) override; // from Shape7 virtual void roll() override; // from Rollable8 };9

10 class Square : public Shape // squares, however, don't roll11 {12 public:13 virtual void draw() const override;14 virtual void rotate(int degrees) override;15 };

Inheritance and Role Modelling : Role Modelling : Modelling More Than One Role 46 / 66

Page 48: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Using Rollable

1 double calculateDistanceRolled(Rollable& rollable_item)2 {3 // this function can operate on Circles and Wheels4 // but not Squares5

6 rollable_item->roll();7 // ...8 }

Inheritance and Role Modelling : Role Modelling : Modelling More Than One Role 47 / 66

Page 49: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Viewing the Same Object in Different Roles

1 // create a Circle2 auto circle_ptr = make_shared<Circle>(10);3

4 // see Circle as a Shape only5 shared_ptr<Shape> shape_ptr = circle_ptr;6 shape_ptr->draw();7

8 // see Circle as Rollable only9 shared_ptr<Rollable> rollable_ptr = circle_ptr;10 rollable_ptr->roll();

Inheritance and Role Modelling : Role Modelling : Modelling More Than One Role 48 / 66

Page 50: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

The Liskov Substitution Principle (LSP)

A subtype is a type that is related to another type — the supertype — by thenotion of substitutability, meaning that client code, written to operate oninstances of the supertype can safely operate on instances of the subtype becausethey behave in the same way.Instances of subtype will not surprise client code by having expectations notmentioned in supertype’s specification i.e virtual function overrides must requireno more than their base versionsInstances of subtype will not surprise client code by failing to meet guaranteesmade in supertype’s specification i.e virtual function overrides must promise noless than their base versionsBehavioral subtyping is considerably stronger than what can be implemented in atype checker

Inheritance and Role Modelling : Modelling Dilemmas : The Liskov Substitution Principle 49 / 66

Page 51: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

LSP Exercise

Is a Square substitutable for a Rectangle?

class Square: public Rectangle{public:

Square(int side):Rectangle(side, side){}

// assume perimeter is virtual in base classvirtual int perimeter() override{

return (base() * 4);}

};

Inheritance and Role Modelling : Modelling Dilemmas : The Liskov Substitution Principle 50 / 66

Page 52: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

The Liskov Substitution Principle (LSP)

Inheritance and Role Modelling : Modelling Dilemmas : The Liskov Substitution Principle 51 / 66

Page 53: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Refused Bequest

Penguins cannot fly. How would you deal with this given the following design?

class Bird {public:

// birds can flyvirtual void fly() = 0;...

};

// penguins are birdsclass Penguin: public Bird {

...};

Inheritance and Role Modelling : Modelling Dilemmas : Refused Bequest 52 / 66

Page 54: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Base class Shape Mixes Role Modelling with Implementation

class Shape{public:

// interface to users of Shapesvirtual void draw() const = 0;virtual void rotate(int degrees) = 0;

private:// common data for implementers of ShapePoint center_;Colour col_;

};

Inheritance and Role Modelling : Modelling Dilemmas : Modelling Roles Which Include Implementation Details 53 / 66

Page 55: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Shape Hierarchy - Example

Refer to your handout for the complete shape hierarchy, and do the following:Draw a diagram illustrating the dependencies between the .h and .cpp files.What happens in terms of compiling if the definition of Colour or Pointchanges?

class Shape // base class

class Circle : public Shape // derived

class Triangle : public Shape // derived

Inheritance and Role Modelling : Modelling Dilemmas : Modelling Roles Which Include Implementation Details 54 / 66

Page 56: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Example Continued: Using the Shape Class

void RotateDrawing(vector<shared_ptr<Shape>>& drawing){

for (const auto& shape_ptr : drawing){

shape_ptr->rotate(45);}

}

Inheritance and Role Modelling : Modelling Dilemmas : Modelling Roles Which Include Implementation Details 55 / 66

Page 57: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

A Better Approach — Using a Pure Interface

A pure interface is a class consisting entirely of pure virtual functions and no state(data members)Such interfaces are valuable because they model roles without mixing inimplementation detailsBase classes should often define functionality but not implement it — in thissituation provide a pure interface

Inheritance and Role Modelling : Modelling Dilemmas : Modelling Roles Which Include Implementation Details 56 / 66

Page 58: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Shape as a Pure Interface

The New Shape Class

class Shape {public:

// pure interface for users of Shape - all functions are pure virtualvirtual void draw() const = 0;virtual void rotate(int degrees) = 0;// ...

// no data members};

Interfaces are so important that Java and C# have introduced the interfacekeyword.

Inheritance and Role Modelling : Modelling Dilemmas : Modelling Roles Which Include Implementation Details 57 / 66

Page 59: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Using a Pure Interface: The New Circle Class

class Circle : public Shape {public:

virtual void draw() const override;virtual void rotate(int degrees) override;// ...

private:Point center_;unsigned int radius_;Colour col_;// ...

};

Inheritance and Role Modelling : Modelling Dilemmas : Modelling Roles Which Include Implementation Details 58 / 66

Page 60: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Using a Pure Interface: The New Triangle Class

class Triangle : public Shape {public:

virtual void draw() const override;virtual void rotate(int degrees) override;// ...

private:Point a_, b_, c_;Colour col_;

// ...};

The users of Shape are now insulated from any changes to Point or Colour.

Inheritance and Role Modelling : Modelling Dilemmas : Modelling Roles Which Include Implementation Details 59 / 66

Page 61: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

How Can We Still Follow the DRY Principle?

The problem is that some member functions and/or data members might genuinely becommon to all or a number of derived classes.

Two solutions to this are:1 Use composition instead of inheritance — often the commonality that is being

inherited is really a separate, distinct concept. Eg. consider a GPS co-ordinate, ageo-cache and a waypoint.

2 Use multiple inheritance and mix-in classes (non-public inheritance)

Inheritance and Role Modelling : Modelling Dilemmas : Modelling Roles Which Include Implementation Details 60 / 66

Page 62: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

How Can We Still Follow the DRY Principle?

The problem is that some member functions and/or data members might genuinely becommon to all or a number of derived classes.

Two solutions to this are:1 Use composition instead of inheritance — often the commonality that is being

inherited is really a separate, distinct concept. Eg. consider a GPS co-ordinate, ageo-cache and a waypoint.

2 Use multiple inheritance and mix-in classes (non-public inheritance)

Inheritance and Role Modelling : Modelling Dilemmas : Modelling Roles Which Include Implementation Details 60 / 66

Page 63: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Exploding Class Hierachies

+Move() +Vocalise()

Animal

Bird Dog Mouse

Here, all of the behaviours of Animal vary together.Inheritance and Role Modelling : Modelling Dilemmas : Exploding Class Hierarchies 61 / 66

Page 64: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Consider an Employee Class

class Employee {public:

// different calculations are used depending on the type of employeevirtual double earnings() const = 0;

virtual ~Employee();};

class FixedRateWorker: public Employee {//...

class CommissionWorker: public Employee {//...

Inheritance and Role Modelling : Modelling Dilemmas : Exploding Class Hierarchies 62 / 66

Page 65: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

The Employee Class Hierarchy

+earnings()

Employee

FixedRateWorker CommissionWorker

Inheritance and Role Modelling : Modelling Dilemmas : Exploding Class Hierarchies 63 / 66

Page 66: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Employees and Medical Aid Plans

But we now realise that we need to calculate medical aid contributions for employees.In class Employee we want to provide a function which returns the Employee’smedical aid contributions.

The calculation to determine the medical aid contribution changes depending on whichmedical aid plan the employee is on (Discovery Health, MediCover etc).It varies independently of an employee’s earnings.(Also, some employees are not on medical aid.)

ExerciseDraw a UML diagram, and possibly give some code, to illustrate how employees andmedical aid plans are related.

Inheritance and Role Modelling : Modelling Dilemmas : Exploding Class Hierarchies 64 / 66

Page 67: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Summary

Inheritance and Role Modelling : : 65 / 66

Page 68: Inheritance and Role Modelling - GitHub Pages · Inheritance and Role Modelling : A Tale of Two Uses of Inheritance : ... 2006, in Practices of an Agile Developer Inheritance and

Inheritance and Polymorphism

Inheritance and polymorphism are key to OO designAvoid using inheritance to simply gain access to the base class’s implementationInheritance and polymorphism are best used to model a role (or roles) that objectscan fulfillDefault and mandatory implementations can be provided for subtypesBe aware of modelling pitfalls:

LSP violationsRefused bequestsExploding hierarchies

Consider providing pure interfaces for subtypes to implement

Inheritance and Role Modelling : : 66 / 66