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