Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

Cosc346 – Multiple Inheritance – Lecture 11 Cosc346 – Multiple Inheritance – Lecture 11

Multiple Inheritance Problem of Single Inheritance


• Where a child class can inherit from more than • We can divide the world into an infinite number
one parent class directly of hierarchies
• Supported in C++, Eiffel • For complex problems strict hierarchies almost
always end up with trade-offs and ambiguities.
• Not supported in Java, C#
• Chapter 13 of Budd

1 2

Cosc346 – Multiple Inheritance – Lecture 11 Cosc346 – Multiple Inheritance – Lecture 11

Example Solutions
Object
• Make Complex a subclass of Number and
override Ordered methods
Ordered
• Avoid inheritance, and redefine all methods
• Use a partial inheritance hierarchy
Char Number
• Use multiple inheritance

Complex? Integer Float Fraction

3 4

Cosc346 – Multiple Inheritance – Lecture 11 Cosc346 – Multiple Inheritance – Lecture 11

Problems Name Ambiguity


• Name ambiguity • The same name can mean different things to
• Substitutability different ancestors
• Common ancestors
CardDeck GraphicalObject
• Implementation problems (next lecture)
draw() draw()

GraphicalCardDeck
5 6
Cosc346 – Multiple Inheritance – Lecture 11 Cosc346 – Multiple Inheritance – Lecture 11

Solution A Solution B
• Explicit disambiguation: • With different type signatures, can use straight
GraphicalCardDeck gcd; overloading:
gcd.CardDeck::draw(); class GCD : public CardDeck, public GO {
gcd.GraphicalObject::draw(); public:
virtual Card *draw(){
return CardDeck::draw();};
• A bit ugly
virtual void draw(GraphicsContext &g){
GraphicalObject::draw(g);};
};

7 8

Cosc346 – Multiple Inheritance – Lecture 11 Cosc346 – Multiple Inheritance – Lecture 11

Solution B2 Solution C
• With the same type signatures, we're in trouble:
class GCD : public CardDeck, public GO {
class GCD: public CardDeck, public GO {
public:
public:
using CardDeck::draw;
virtual void draw(){
using GraphicalObject::draw;
return CardDeck::draw();}
};
virtual void paint(){GO::draw();};
};

GraphicalObject *g = new GraphicalCardDeck();


g->draw();

9 10

Cosc346 – Multiple Inheritance – Lecture 11 Cosc346 – Multiple Inheritance – Lecture 11

Solution D
class CardDeckParent : public CardDeck { Solution D
virtual void draw(){cardDeckdraw();};
virtual void cardDeckDraw(){
GraphicalCardDeck *gcd = new GCD();
CardDeck::draw();};
CardDeck *cd = dynamic_cast<CardDeck*>(gcd);
};
class GraphicalObjectParent: public GO { GraphicalObject *go =
dynamic_cast<GraphicalObject*>(gcd);
virtual void draw(){goDraw();};
virtual void goDraw(){GO::draw();}; cd->draw(); // ok
}; go->draw(); // ok
class GraphicalCardDeck:public CDP,public GOP { gcd->cardDeckDraw(); // ok
virtual void cardDeckDraw(){ gcd->goDraw(); // ok
CDP::cardDeckDraw();}; gcd->draw(); // error - ambiguous
virtual void goDraw(){GOP::goDraw();};
};

11 12
Cosc346 – Multiple Inheritance – Lecture 11 Cosc346 – Multiple Inheritance – Lecture 11

Common Ancestors C++ Example


• The “diamond of death”:
Stream
A A A

InStream OutStream
B C B C

InOutStream
D D
13 14

Cosc346 – Multiple Inheritance – Lecture 11 Cosc346 – Multiple Inheritance – Lecture 11

Virtual Inheritance Inner Classes


class Stream {...};
• In languages which allow inner classes (Java, C#,
class InStream: public virtual Stream {...};
class OutStream: public virtual Stream {...};
D), we can simulate multiple inheritance after a
class InOutStream: fashion:
public InStream, public OutStream {...};

• The ambiguity occurs in InOutStream, but the


solution involves the definitions of InStream and
OutStream.

15 16

Cosc346 – Multiple Inheritance – Lecture 11 Cosc346 – Multiple Inheritance – Lecture 11

Inner Classes Strategy


class GraphicalCardDeck extends CardDeck {
public void draw() { // draw a card from a deck}
Problem: How do you allow the algorithm that is
private class DrawingClass extends GraphicalObject { used to solve a particular problem be easily and
public void draw() {// draw a card on screen} dynamically changed by the client?
}
private DrawingClass drawer = new DrawingClass;
Solution: Define a family of algorithms with a
public GraphicalObject myDrawingObject(){ similar interface.
return drawer;};

17 18
Cosc346 – Multiple Inheritance – Lecture 11 Cosc346 – Multiple Inheritance – Lecture 11

Example Consequences
class SortableVector: public vector {
private:
Sorter _sorter; • Families of related algorithms.
public: void sort() {
_sorter.sort(this);
• Alternative to subclassing.
}}
class Sorter {
• Eliminates conditional statements.
public: • Clients must be aware of different strategies.
virtual void sort(SortableVector tosort)=0;
} • Increases the number of objects.
class QuickSorter : public Sorter {
public: void sort(SortableVector tosort) {
...
}}

19 20

You might also like