Chapter 13, Outline
Introduction to Object Oriented Programming, 3rd Ed
Chapter 13
Multiple Inheritance
Outline
- Roadmap
- Inheritance as Categorization
- Inheritance as Combination
- An Example -- Complex Numbers
- Possible Solutions
- Numbers as Combinations
- Another Example -- Walking Menus
- Problem with MI - Name Ambiguity
- One Solution: Redefinition
- Problem with Redefinition Solution
- Other Approaches to Name Ambiguity
- Multiple Inheritance of Interfaces
- Inheritance from Common Ancestors
- Data Field in Common Ancestor
- Inner Classes
- Chapter Summary
Other Material
Roadmap
In this chapter we will investigate some of the
problems that can arize when a language
allows a child class to have multiple parents.
- Name ambiguity
- Impact on substitution
- The Problem of Common Ancestors
Intro OOP, Chapter 13, Slide 01
Inheritance as Categorization
In one sense, the process of inheritance is a form of categorization.
A TextWindow is a type of Window, so class TextWindow inherits from
class Window.
But in the real world, most objects can be categorized in a variety of
ways. The author of the textbook is
- North American
- Male
- Professor
- Parent
None of these are proper subsets of the other, and we cannot
make a single rooted inheritance hierarchy out of them.
Intro OOP, Chapter 13, Slide 02
Inheritance as Combination
Instead, real world objects are combinations of features from different
classification schemes, each category giving some new insight into the whole:
- Author is North American, and
- Author is Male, and
- Author is a Professor, and
- Author is a Parent.
Note that we have not lost the is-a relationship; it still applies in
each case.
Intro OOP, Chapter 13, Slide 03
CS Example - Complex Numbers
Two abstract classifications
-
Magnitude - things that can be compared to each other.
-
Number - things that can perform arithmetic
Three specific classes
-
Integer - comparable and arithmetic
-
Char - comparable but not arithmetic
-
Complex - arithmetic but not comparable
Intro OOP, Chapter 13, Slide 04
Possible Solutions
- 1.
- Make Number subclass of Magnitude, but redefine comparison operators in
class complex to give error message if used.
(subclassing for limitation)
- 2.
- Don't use inheritance at all - redefine all operators in all classes.
(flattening the inheritance tree).
- 3.
- Use part inheritance, but simulate others - use Number, but have each
number implement all relational operators.
- 4.
- Make Number and Magnitude independent, and have Integer inherit from both.
(multiple inheritance).
Intro OOP, Chapter 13, Slide 05
Inheritance as a form of Combination
Intro OOP, Chapter 13, Slide 06
Another Example - Walking Menus
-
A Menu is a structure charged with displaying itself when selected
by the user.
-
A Menu maintains a collection of MenuItems.
-
Each MenuItem knows how to respond when selected.
-
A cascading menu is both a MenuItem and a Menu.
Intro OOP, Chapter 13, Slide 07
Problem with MI - Name Ambiguity
What happens when same name is used in both parent classes.
-
A CardDeck knows how to draw a Card.
-
A GraphicalItem knows how to draw an image on a screen.
-
A GraphicalCardDeck should be able to draw. which?
Intro OOP, Chapter 13, Slide 08
One Solution: Redefinition
One solution is to redefine one or the other operation in the child class.
class GraphicalCardDeck : public CardDeck, public GraphicalObject {
public:
virtual void draw () { return CardDeck::draw(); }
virtual void paint () { GraphicalObject::draw(); }
}
GraphicalCardDeck gcd;
gcd->draw(); // selects CardDeck draw
gcd->paint(); // selects GraphicalObject draw
Intro OOP, Chapter 13, Slide 09
Problem with Redefinition Solution
The redefinition solution is not without cost, however.
Now what happens when we run up against the principle of substitution?
GraphicalObject * g = new GraphicalCardDeck();
g->draw(); // opps, doing wrong method!
This problem can be mitigated, but the solution is complex and not perfect.
Intro OOP, Chapter 13, Slide 10
Other Approaches to Name Ambiguity
Other languages use different approaches to solving the problem
of ambiguous names
- Eiffel uses the ability to rename features from the parent class.
A polymorphic variable accessing through the parents name will access
the renamed feature in the child.
- CLOS and Python resolve ambiguous names by the order in which the
parent classes are listed. The first occurrence of the name found in
a systematic search is the one selected.
Intro OOP, Chapter 13, Slide 11
Multiple Inheritance of Interfaces
Multiple inheritance of interfaces does not present the same problem
of name ambiguity as does multiple inheritance of classes.
- Either the ambiguous methods in the parent classes have different
type signatures, in which case there is no problem, or
- The ambiguous methods in the parent classes have the same signature.
Still no problem, since what is inherited is only a specification,
not an implementation.
This is why Java permits multiple inheritance of interfaces, not of
classes.
Nevertheless, C# does not permit the same method name to be inherited
from two parent interfaces.
Intro OOP, Chapter 13, Slide 12
Inheritance from Common Ancestors
Another problem with MI occurs when parent classes have a common root
ancestor. Does the new object have one or two instances of the
ancestor?
Intro OOP, Chapter 13, Slide 13
Data Field in Common Ancestor
Imagine that the common ancestor declares a data member. Should the
child class have one copy of this data field, or two?
Both answers can be justified with examples.
C++ gets around this by introducing the idea of a virtual parent class.
If your parent is virtual there is one copy, and if not there is two.
Not a perfect solution, and makes the language complicated.
Intro OOP, Chapter 13, Slide 14
Inner Classes
The ability to next classes in C++ and Java provides a mechanism that
is nearly equivalent to multiple inheritance, without the semantic problems.
class Child extends ParentOne {
...
class InnerChild extends ParentTwo {
...
// can access both parents
}
}
Within the inner class you can access methods from both parent classes.
This idiom is used a lot in Java. Solves many problems that
would otherwise be addressed using MI.
Not exactly equivalent to MI, but very close.
Intro OOP, Chapter 13, Slide 15
Chapter Summary
In this chapter we have explored some of the problems that arise
of the concept of multiple inheritance.
- Name ambiguity
- Impact on substitution
- The Problem of Common Ancestors
Intro OOP, Chapter 13, Slide 16