l4: multiple inheritance

19
SFDV4001 / OOP with C++ / Lecture 4 / Polymorphism 1 L4: Multiple Inheritance Introduction Problems of Single Inheritance and solutions Problems of Multiple Inheritance: Name ambiguity Substitutability Common ancestors 5 Solutions to the Problems Virtual Inheritance Inner Classes Chapter 13 of Budd

Upload: tate-quinn

Post on 02-Jan-2016

28 views

Category:

Documents


0 download

DESCRIPTION

L4: Multiple Inheritance. Introduction Problems of Single Inheritance and solutions Problems of Multiple Inheritance: Name ambiguity Substitutability Common ancestors 5 Solutions to the Problems Virtual Inheritance Inner Classes Chapter 13 of Budd. Multiple Inheritance. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism1

L4: Multiple Inheritance Introduction

Problems of Single Inheritance and solutions

Problems of Multiple Inheritance:

• Name ambiguity• Substitutability• Common ancestors

5 Solutions to the Problems

Virtual Inheritance

Inner Classes

Chapter 13 of Budd

Page 2: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism2

Multiple Inheritance

• Where a child class can inherit from more than one parent class directly

• Supported in C++, Eiffel

• Not supported in Java, C#

Page 3: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism3

A QuoteMultiple inheritance allows several objects to act

as base objects ... The characteristics of several different object classes can be combined to make up a new object. For example, say we have an object class CAR and an object class PERSON. We could use both of these to define a new object class CAR-OWNER …

Sommerville, “Software Engineering”, 4th Edition

Page 4: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism4

Problem of Single Inheritance

• We can divide the world into an infinite number of hierarchies

• For complex problems strict hierarchies almost always end up with trade-offs and ambiguities.

Page 5: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism5

ExampleObject

Ordered

Char Number

Integer Float FractionComplex?

Page 6: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism6

Solutions

• Make Complex a subclass of Number and override Ordered methods

• Avoid inheritance, and redefine all methods• Use a partial inheritance hierarchy• Use multiple inheritance

Page 7: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism7

Problems of Multiple Inheritance

• Name ambiguity• Substitutability• Common ancestors

Page 8: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism8

Name Ambiguity

• The same name can mean different things to different ancestors

GraphicalCardDeck

CardDeck

draw()

GraphicalObject

draw()

Page 9: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism9

Solution A

• Explicit disambiguation:GraphicalCardDeck gcd;

gcd.CardDeck::draw();

gcd.GraphicalObject::draw();

Page 10: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism10

Solution B• With different type signatures, can use straight

overloading:

class GCD : public CardDeck, public GO {

public:

virtual Card *draw(){

return CardDeck::draw();};

virtual void draw(GraphicsContext &g){

GraphicalObject::draw(g);};

};

Page 11: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism11

Solution B2

class GCD : public CardDeck, public GO {

public:

using CardDeck::draw;

using GraphicalObject::draw;

};

Page 12: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism12

Solution C• With the same type signatures, we're in trouble:

class GCD: public CardDeck, public GO {

public:

virtual void draw(){

return CardDeck::draw();}

virtual void paint(){GO::draw();};

};

GraphicalObject *g = new GraphicalCardDeck();

g->draw();

Page 13: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism13

Solution Dclass CardDeckParent : public CardDeck {

virtual void draw() {cardDeckdraw();};virtual void cardDeckDraw() {CardDeck::draw();};

};class GraphicalObjectParent: public GO {

virtual void draw() {goDraw();};virtual void goDraw() {GO::draw();};

};class GraphicalCardDeck:public CDP,public GOP {

virtual void cardDeckDraw() {CDP::cardDeckDraw();};

virtual void goDraw() {GOP::goDraw();};};

Page 14: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism14

Solution DGraphicalCardDeck *gcd = new GCD();

CardDeck *cd = dynamic_cast<CardDeck*>(gcd);

GraphicalObject *go = dynamic_cast<GraphicalObject*>(gcd);

cd->draw(); // ok

go->draw(); // ok

gcd->cardDeckDraw(); // ok

gcd->goDraw(); // ok

gcd->draw(); // error - ambiguous

Page 15: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism15

Common Ancestors

• The “diamond of death”:

A

B C

D

A A

B C

D

Page 16: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism16

C++ Example

Stream

InStream OutStream

InOutStream

InStream and OutStream inherit and override a method in Stream. InOutStream inherits the same method.

Page 17: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism17

Virtual Inheritance

class Stream {...};

class InStream: public virtual Stream {...};

class OutStream: public virtual Stream {...};

class InOutStream:

public InStream, public OutStream {...};

• The ambiguity occurs in InOutStream, and the solution involves the definitions of InStream and OutStream.

Page 18: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism18

Inner Classes

• In languages which allow inner classes (Java, C#), we can simulate multiple inheritance after a fashion:

Page 19: L4: Multiple Inheritance

SFDV4001 / OOP with C++ / Lecture 4 /

Polymorphism19

Java Inner Classesclass GraphicalCardDeck extends CardDeck {

public void draw() { // draw a card from a deck}

private class DrawingClass extends GraphicalObject {

public void draw() {// draw a card on screen}

}

private DrawingClass drawer = new DrawingClass;

public GraphicalObject myDrawingObject(){

return drawer;};

}