Download presentation
Presentation is loading. Please wait.
Published byPatricia Henderson Modified over 9 years ago
1
1 COSC2767: Object-Oriented Programming Haibin Zhu, Ph. D. Professor of CS, Nipissing University
2
2 More examples for Inheritance u C++ inheritance (inheritance.cpp) u C++ overloading and overriding (overinh.cpp) u ---No overloading across scopes in C++! u Java inheritance (Inherit.java)
3
3 Lecture 4 Subclasses, subtype and Multiple Inheritance
4
4 Subtype, Subclass and Substitution u The distinction between subtype and subclass is important because of their relationship to substitution. u Recall the argument that asserted a child class has the same behavior as the parent, and thus a variable declared as the parent class should in fact be allowed to hold a value generated from a child class. u But does this argument always hold true?
5
5 What is a type? u Type is a shorthand for specifications. u What do we mean when we use the term type in describing a programming language? u A set of values. (The type int, for example, describes -2147483648 to 2147483647) u A set of operations. (We can do arithmetic on ints, not on booleans). u A set of properties. (If we divide 8 by 5 we are not surprised when the result is 1, and not 1.6). u What about when we consider classes (or interfaces) as a system for defining types?
6
6 What is a subtype? u if A is a subclass of B, then an instance of class A may be used in any context where an instance of type B is expected; thus we say A is a subtype of B. u For example: u A=long int, B = int u S = double, T = float
7
7 The Definition of Subtype u So now we can better understand the concept of a subtype. A subtype preserves the meaning (purpose, or intent) of the parent. u Problem: meaning is extremely difficult to define. Think about how to define the LIFO characteristics of a stack.
8
8 The Problem of Defining Meanings u Consider how we might define a Stack ADT in Java: u interface Stack { u public void push (Object value); u public Object top (); u public void pop (); u } u Notice how the interface itself says nothing about the LIFO property, which is the key defining feature of a stack. Is the following a stack? u class NonStack implements Stack { u public void push (Object value) { v = value; } u public Object top () { return v; } u public void pop () { v = null; } u private Object v = null; u } u Question: Can an interface be considered as a type?
9
9 Subclasses are not Necessarily Subtypes u It is easy to create a subclass that is not a subtype -- think of NonStack. It is also possible to create subtypes that are not subclasses. Think of Array in Smalltalk. This class is characterized by the following interface: u at: input put: value u at: int u size u But class Dictionary will also support the same interface, and perform similar actions -- but Dictionary is not a subclass of Array.
10
10 The Substitution Paradox u There is a curious paradox that lies at the heart of most strongly typed object-oriented programming languages. u Substitution is permitted, based on subclasses. That is, a variable declared as the parent type is allowed to hold a value derived from a child type. u Yet from a semantic point of view, substitution only makes sense if the expression value is a subtype of the target variable. u If substitution only makes sense for subtypes and not for all subclasses, why do programming languages based the validity of assignment on subclasses?
11
11 The Undecidability of the Subtype Relationship u It is trivial to determine if one class is a subclass of another. It is extremely difficult to define meaning (think of the Stack ADT), and even if you can it is almost always impossible to determine if one class preserves the meaning of another. u One of the classic corollaries of the halting problem is that there is no procedure that can determine, in general, if two programs have equivalent behavior.
12
12 Is This a Problem? u What does it take to create a subclass that is not a subtype? u The new class must override at least one method from the parent. u It must preserve the type signatures. u But it must violate some important property of the parent. u Is this common? Not likely. But it shows you where to look for problem areas.
13
13 Summary of subclasses u To say a class is a subclass of another simply asserts that it is built using inheritance. u By itself, the subclass relationship says nothing about the behavior of the child in relation to the parent. u The term subtype is used to describe a class that matches the behavior of another class. u It is easy to build subclasses that are not subtypes. It is possible (although not as easy) to build subtypes that are not subclasses.
14
14 u Multiple Inheritance
15
15 Inheritance as Categorization u 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. u But in the real world, most objects can be categorized in a variety of ways. The author of the textbook is u North American u Male u Professor u Parent u None of these are proper subsets of the other, and we cannot make a single rooted inheritance hierarchy out of them.
16
16 Inheritance as Combination u Instead, real world objects are combinations of features from different classification schemes, each category giving some new insight into the whole: u Author is North American, and u Author is Male, and u Author is a Professor, and u Author is a Parent. u Note that we have not lost the is-a relationship; it still applies in each case.
17
17 Complex Numbers u Two abstract classifications u Magnitude - things that can be compared to each other. u Number - things that can perform arithmetic u Three specific classes u Integer - comparable and arithmetic u Char - comparable but not arithmetic u Complex - arithmetic but not comparable
18
18 Possible Solutions u Make Number subclass of Magnitude, but redefine comparison operators in class complex to give error message if used. (subclassing for limitation). u Don't use inheritance at all - redefine all operators in all classes. (flattening the inheritance tree). u Use part inheritance, but simulate others - use Number, but have each number implement all relational operators. u Make Number and Magnitude independent, and have Integer inherit from both. (multiple inheritance).
19
19 Inheritance as a form of Combination
20
20 What is Multiple Inheritance? u If class A inherits from more than one class, i.e. A inherits from B1, B2,..., Bn, we speak of multiple inheritance. u This may introduce naming conflicts in A if at least two of its superclasses define properties with the same name.
21
21 Naming Conflicts u Name conflicts between superclasses of a class. u If attributes or methods defined in one superclass have the same name as attributes or methods defined in another superclass.
22
22 Name Ambiguity u What happens when same name is used in both parent classes. u A CardDeck knows how to draw a Card. u A GraphicalItem knows how to draw an image on a screen. u A GraphicalCardDeck should be able to draw. which?
23
23 B1 {//… int x; } B2 {//… int x; public: int getValue(); } B3 {//… int x; public: int getValue(); } A{}A{} Multiple Inheritance and Naming conflicts Ex4-1.cpp
24
24 Conflict Conquering 1. Using the order of the superclasses u If there are more attributes or methods with the same name in different superclasses, the ones occurring in the first class in the list of superclasses are inherited.(Done by the compiler) u If the order is from left to right, then x means the x of B1, and getValue() means the getValue() of B2.
25
25 Conflict Conquering 2. The user can determine u The user can inherit conflicting attributes or methods, but he has to explicitly rename conflicting attributes or methods in the subclass.(Done by the users) u B1::x; or B2::x; u B2::getValue(); or B3::getValue();
26
26 One Solution: Redefinition u To redefine one or the other operation in the child class. u class GraphicalCardDeck : public CardDeck, public GraphicalObject { u public: u virtual void draw () { return CardDeck::draw(); } u virtual void paint () { GraphicalObject::draw(); } u } u GraphicalCardDeck *gcd; u gcd->draw(); // selects CardDeck draw u gcd->paint(); // selects GraphicalObject draw
27
27 Problem with Redefinition Solution u The redefinition solution is not without cost, however. Now what happens when we run up against the principle of substitution? u GraphicalObject * g = new GraphicalCardDeck(); u g->draw(); u // opps, doing wrong method! u This problem can be mitigated, but the solution is complex and not perfect.
28
28 Redefinition Class CardDeckParent : Public CardDeck { Public: Virtual void draw() {cardDeckDraw();} Virtual void cardDeckDraw() {CardDeck::draw()} } Class GraphicalObjectParent : Public GraphicalObject { Public: Virtual void draw() {goDraw();} Virtual void goDraw() {GraphicalObject::draw()} }
29
29 Redefinition Class GraphicalCardDeck: public CardDeckParent, GraphicalObjectParent {public: Virtual void cardDeckDraw() {…} Virtual goDraw() {…} } GraphicalCardDeck *gcd = new Grpahical CardDeck(); CardDeck *cd = gcd; GraphicalObject *go=gcd; Cd->draw(); Go-draw(); Gcd->draw(); //ex4-2.cpp
30
30 Other Approaches to Name Ambiguity u Other languages use different approaches to solving the problem of ambiguous names u 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. u 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.
31
31 Precedence conflicts u We have class A with attribute a, class B which is a subclass of A and redefines attribute a, class C which is also a subclass of A, and class D which is a subclass of B and C (multiple inheritance). u Class D can inherit the redefined version of a from class B or the original version from class C. u Which version of attribute a should be inherited?
32
32 Precedence conflicts class A {a; } class B: public A { } class C: public A {a;//redefined } class D: public B, C {? } Diamond problem.
33
33 Conflict Conquering u The same as the naming conflicts: u Use the order of the superclasses by the compiler; u Use the explicit class name by the users
34
34 Virtual inheritance in C++ u In C++, virtual inheritance is a kind of inheritance that solves some of the problems caused by multiple inheritance (particularly the "diamond problem") by clarifying ambiguity over which ancestor class members to use.C++multiple inheritancediamond problem u The part of the object that belongs to the virtual base class becomes common direct base for the derived class and any next class that derives from it.
35
35 A Problem u class Base u { u public: u virtual void print() const = 0; u }; u class DerivedOne : virtual public Base u { u public: u void print() const u { cout << "DerivedOne\n"; } u };
36
36 u class DerivedTwo : virtual public Base u { public: u void print() const { cout << "DerivedTwo\n"; } u }; u class Multiple : public DerivedOne, public DerivedTwo u { public: u void print() const u { DerivedTwo::print(); } u };
37
37 Solution u int main() u { Multiple both; // instantiate Multiple object u DerivedOne one; // instantiate DerivedOne object u DerivedTwo two; // instantiate DerivedTwo object u // declare array of base-class pointers and initialize u // each element to a derived-class type u Base *array[ 3 ]; u array[ 0 ] = &both; u array[ 1 ] = &one; u array[ 2 ] = &two; u ///… u } u //ex4-3.cpp u // http://www.phpcompiler.org/doc/virtualinheritance.html
38
38 Multiple Inheritance and Composition u Wrong One! class Head {} class Engine {} class Wing{} class Tail {} class Plane: public Head, public Engine, public Wing, public Tail { }
39
39 Multiple Inheritance and Composition u Correct One! class Plane { private: Head head; Engine engines[4]; //4 engines Wing wings[2]; //2 wings Tail tail; public: … }
40
40 Java Interfaces u An interface is like a class, but it provides no implementation. Later, another class can declare that it supports the interface, and it must then give an implementation. u public interface Storing { u void writeOut (Stream s); u void readFrom (Stream s); u }; u public class BitImage implements Storing { u void writeOut (Stream s) { u //... u } u void readFrom (Stream s) { u //... u } u }; u We will have much more to say about interfaces later after we discuss inheritance.
41
41 Java Interfaces u Simple inheritances (extends) for classes u Multiple implementations (implements) for interfaces u Mulinterface.java
42
42 u interface intf1 u { u public void fun1(); u } u interface intf2 u { u public void fun2(); u } u class par{ u int i; u public void fun() u { u System.out.println("Fun!"); u } public class mulinterface extends par implements intf1, intf2{ public void fun1() { System.out.println("Fun1!"); } public void fun2() { System.out.println("Fun2!"); } public static void main(String[] args) { mulinterface p = new mulinterface(); p.fun(); p.fun1(); p.fun2(); }
43
43 Summary of Multiple Inheritance u Name ambiguity u Impact on substitution u The Problem of Common Ancestors
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.