l4: multiple inheritance
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 PresentationTRANSCRIPT
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
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#
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
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.
SFDV4001 / OOP with C++ / Lecture 4 /
Polymorphism5
ExampleObject
Ordered
Char Number
Integer Float FractionComplex?
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
SFDV4001 / OOP with C++ / Lecture 4 /
Polymorphism7
Problems of Multiple Inheritance
• Name ambiguity• Substitutability• Common ancestors
SFDV4001 / OOP with C++ / Lecture 4 /
Polymorphism8
Name Ambiguity
• The same name can mean different things to different ancestors
GraphicalCardDeck
CardDeck
draw()
GraphicalObject
draw()
SFDV4001 / OOP with C++ / Lecture 4 /
Polymorphism9
Solution A
• Explicit disambiguation:GraphicalCardDeck gcd;
gcd.CardDeck::draw();
gcd.GraphicalObject::draw();
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);};
};
SFDV4001 / OOP with C++ / Lecture 4 /
Polymorphism11
Solution B2
class GCD : public CardDeck, public GO {
public:
using CardDeck::draw;
using GraphicalObject::draw;
};
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();
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();};};
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
SFDV4001 / OOP with C++ / Lecture 4 /
Polymorphism15
Common Ancestors
• The “diamond of death”:
A
B C
D
A A
B C
D
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.
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.
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:
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;};
}