+ All Categories
Home > Documents > CSCI 383 Object-Oriented Programming Design Lecture 19 Martin van Bommel.

CSCI 383 Object-Oriented Programming Design Lecture 19 Martin van Bommel.

Date post: 18-Jan-2018
Category:
Upload: rhoda-blankenship
View: 218 times
Download: 0 times
Share this document with a friend
Description:
Fall 2010CSCI 383 Lecture 19 M. van Bommel 3 Inheritance as Classification But in the real world, most objects can be categorized in a variety of ways. A person can be a Male Professor Parent None of these are proper subsets of the other, Cannot make a single rooted inheritance hierarchy out of them
29
CSCI 383 Object-Oriented Programming & Design Lecture 19 Martin van Bommel
Transcript
Page 1: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

CSCI 383

Object-Oriented Programming & Design

Lecture 19

Martin van Bommel

Page 2: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 2

Inheritance as Classification In one way, the is-a relationship is a form of

classification E.g., A TextFile is a type of File so class TextFile

inherits from class File

File

TextFile

Page 3: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 3

Inheritance as Classification But in the real world, most objects can be

categorized in a variety of ways. A person can be a Male Professor Parent

None of these are proper subsets of the other, Cannot make a single rooted inheritance

hierarchy out of them

Page 4: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 4

Inheritance as Combination Instead, real world objects are combinations of

many nonoverlapping categories, each category contributing something to the result

Note that we have not lost the is-a relationship; it still applies in each case

Male Professor

Parent

Page 5: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 5

Multiple Inheritance Modeling this behavior in programs seems to

call for the concept of multiple inheritance An object can have two or more different parent

classes and inherit both data and behavior from each

Male Professor Parent

Page 6: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 6

Multiple Inheritance It wouldn't be an exaggeration to say that

multiple inheritance has stirred more controversy and heated debates than has any other C++ feature

Yet the truth is that multiple inheritance is a powerful and effective feature - when used properly

What is a good model?

Page 7: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 7

Incomparable Complex Numbers A portion of the Smalltalk class hierarchy

Where do complex numbers fit?

Object

Boolean Magnitude Collection

Char Number Point Set KeyedCollectionTrue False

Integer Float Fraction

things that can be compared to each other

things that can perform arithmetic

Page 8: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 8

Possible Solutions Make Number subclass of Magnitude, but redefine

comparison operators in class Complex to give error message if used (e.g., subclassing for limitation)

Don't use inheritance at all - redefine all operators in all classes (e.g., flattening the inheritance tree)

Use part inheritance, but simulate others (e.g., use Number, but have each number implement all relational operators)

Make Number and Magnitude independent, and have Integer inherit from both (i.e., multiple inheritance)

Page 9: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 9

Possible Solutions

Magnitude Number

Char Integer Complex

Page 10: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 10

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

Page 11: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 11

Multiple Inheritance in C++ C++ supports multiple inheritance (i.e., a class

may be derived from more than one base class) C++ syntax:

class Derived: public Base1, public Base2, public Base3, protected Base4 { ... };

Example:class passengerVehicle { ... };class trainCar { ... };

class passengerCar: public passengerVehicle, public trainCar { ... };

Handout #5

Page 12: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 12

The Ambiguity Problem Circumstances:

Let Derived be inherited from Base1 and Base2 All feature names inside Base1 are distinct All feature names inside Base2 are distinct All feature names inside Derived should be distinct

Ambiguity problem: the same feature name X occurs both in Base1 and in Base2 The problem does not occur in single inheritance

If the same feature name occurs both in Derived and in Base, then no ambiguity occurs. Why?

Page 13: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 13

The Ambiguity Problem In handout #5, what would happen if we

attempted to print the data members of derived by accessing them individually instead of using the overloaded operator<<

cout << “Object derived contains:\n” << “Integer: “ << derived.getData() << “\nCharacter: “ << derived.getData() << “\nReal number: “ << derived.getReal() << “\n\n“;

Page 14: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 14

Coincidental vs. Inherent Ambiguity Coincidental ambiguity occurs when the

duplicated names Base1::X and Base2::X are unrelated Ambiguity is a coincidence Same name, distinct entities

Inherent ambiguity occurs when Base1 and Base2 derive from a common Base, in which X occurs Ambiguity is inherent Same name, same entity

Page 15: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 15

Ambiguity Resolution Approaches Forbid the inheritance as given. Force the designer

of Base1 and/or Base2 to resolve the ambiguity Unreasonable: Good names are rare. In many cases,

multiple inheritance marries together two distinct inheritance hierarchies, sometimes supplied by different vendors

Impossible: In cases of repeated inheritance Force the designer of Derived to resolve all

ambiguities In Eiffel, the compiler does not allow a class in which an

ambiguity exists. The designer must rename all ambiguous features

In C++, a good designer will override all ambiguous features. This is not always possible since one cannot override data members

Page 16: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 16

Ambiguity Resolution in C++ Scenario

An inherited function/data member is used (inside or outside the class)

The compiler checks that the name is defined in exactly one (direct/indirect) base class

Error message produced if name is defined in more than one class

Ambiguity should be resolved before compilation can proceed Use qualified names (::) to specify exactly one derived

member

Page 17: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Fall 2010 CSCI 383 Lecture 19 M. van Bommel 17

Ambiguity Resolution in C++ In handout #5, if we wanted to print the data

members of derived by accessing them individually instead of using the overloaded operator<<, we could use the scope resolution operator (::) to resolve the ambiguitycout << “Object derived contains:\n” << “Integer: “ << derived.Base1::getData() << “\nCharacter: “ << derived.Base2::getData() << “\nReal number: “ << derived.getReal() << “\n\n“;

Drawbacks Client should be aware of implementation details Late detection of errors

Page 18: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

One Solution: Redefinition/Renaming

By redefinition we mean a change in the operation of a command such as what happens when a virtual method is overridden in a subclass

By renaming we simply mean changing the name by which a method is invoked without altering the command’s functionalityclass Derived:public Base1, public Base2 { public:...int getData() const {return Base1::getData();}char getCharData() const {return Base2::getData();}double getReal() const {return real;}...};

Page 19: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Problem with Redefinition Solution While the redefinition of the function getData

solves the problem when a Derived object is used in isolation, further problems may arise when we consider the implications of the principle of substitution

Suppose getData is defined as a virtual function in Base1, Base2, and Derived

Base2* b = new Derived(7,’A’,3.5);cout << b->getData();

// this may not be what was intended

Page 20: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Diamond of Death

Another common problem occurs when parent classes have a common root ancestor

Occurs in every large system Must occur if the inheritance hierarchy has a common

root

Does the new object have one or two instances of the ancestor?

Think of an example in which we would like to keep two instances

A

B C

D

Page 21: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Diamond of Death Classical example: In C++ standard library,

multiple inheritance is used to form the class iostream

Handout #6

ios

istream ostream

iostreamifstream ofstream

fstream

Page 22: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Approaches to Repeated Inheritance

Forbid the situation A diamond occurs naturally in many cases Demand complicates the design

Single copy of common base class Not always what we want

Multiple copies of common base class Not always what we want

Page 23: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Approaches to Repeated Inheritance

Either single or multiple copies of common base class

Eiffel’s approach: decision made by designer of D C++’s approach: decision made by designer B and C

A

B C

D

Page 24: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Approaches to Repeated Inheritance

In C++ this problem is overcome through the use of the virtual modifier in the parent class list

The virtual keyword indicates that the superclass may appear more than once in descendant classes of the current class but that only one copy of the superclass should be included

class ios { ... };class istream: virtual public ios { ... };class ostream: virtual public ios { ... };class iostream: public istream, public ostream { ... };

Page 25: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Planning for the Diamond Problemclass Person {

...void print(ostream& out){

// Print person data (e.g., name, gender, etc) }};

class Student: virtual public Person {...void print(ostream& out){

Person::print(out);// Print student data (e.g., courses, year, etc)

}};

Page 26: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Planning for the Diamond Problem

class Teacher: virtual public Person {...void print(ostream& out) {Person::print(out)// Print teacher data (e.g., salary, courses, etc)

};

class TeachingAssistant: public Student, public Teacher {...void print(ostream& out) {Student::print(out);Teacher::print(out);// Print assistant data (e.g., supervisor, etc)

};

Do you see any problem? Fix this problem (DONE IN CLASS)

Page 27: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Cross Delegation Handout #7 Notice how a class that DerivedOne knows

nothing about will supply the override of a virtual function invoked by DerivedOne::foo()

This “cross delegation” can be a powerful technique for customizing the behavior of polymorphic classes

Page 28: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Constructors and Virtual Base Class?

class V { public: V(const char* s){ cout << s;}

};

class B1: virtual public V{public: B1(const char* s):V(“B1”){

cout << s;}};

class B2: virtual public V{public: B2(const char* s):V(“B2”){

cout << s;}};

class D: public B1, public B2 { public: D(void):B1(“DB1”),B2(“DB2”) {}

};

What will be printed when instantiating object of class D?

Page 29: CSCI 383 Object-Oriented Programming  Design Lecture 19 Martin van Bommel.

Construction of a Virtual Base Class

Work around 1 Define a default constructor in V

Work around 2 Call V’s constructor directly from the constructor of D

Virtual bases are initialized by the initializer of the most derived class, other initializers are ignored

Virtual bases may be initialized in a constructor of a derived class even if they are not immediate base classes

Practically speaking, this means that when you create a class that has a virtual base class, you must be prepared to pass whatever parameters are required to call the virtual base class's constructor

This might mean that the most-derived class's constructor needs more parameters than you might otherwise think


Recommended