Chapter 6 Part 1 Generalization Inheritance Polymorphism 1
















































- Slides: 48

Chapter 6 Part 1 Generalization: Inheritance & Polymorphism 1

Generalization versus Abstraction z. Frequently confused, but distinct z. Abstraction y. Simplify the description of something z. Generalization y. Find common properties in a set of abstractions 2

Generalization “Identification, and possible organization, of common/shared properties of an abstraction” z. Hierarchy This chapter focuses on these first two. z. Polymorphism z. Genericity z. Patterns 3

Generalization: 4 Kinds z. Hierarchy: Graph representing “is a” relationship z. Polymorphism (“many forms”): Loop to “iterate” through list works for arrays or linked list z. Genericity: “Parameterized” object: Sort object w/ type (int) parameter z. Patterns: Way to structure objects (e. g. , client/server system) 4

Hierarchy z. Represented by generalize/specialize graph z. Based on “is-a” relationship z. Is a form of knowledge representation z. Extendable without redefining everything z. Specialization can be added to proper subset of hierarchy 5

Hierarchy A generalization based on an “is-a” relation 6

Inheritance z. Terminology y. Base class (superclass) y. Derived class (subclass) z. Important Dimensions y. Programming: implement efficiently a set of related classes (mechanical) y. Design: organize coherently the concepts in an application domain (conceptual) y. Software Engineering: design for flexibility and extensibility in software systems (logical) 7

Section 6. 2: The Number Class Abstraction of an integer number class Number { private: that can be incremented int value; Text. Box* text. Box; public: Number(int init. Value = 0); // start at init. Value void Show. In (Text. Box& tbox); // place to display value void Show(); // display current value void Next(); // increment void Reset(); // get new value from user int Value(); // return current value ~Number(); }; 8

The Cycler Class class Cycler { Abstraction of a number that can be private: int value; incremented but is constrained to a int base; range of 0 to base b. Text. Box* text. Box; public: Cycler(int b = 10); // modulo base b void Show. In (Text. Box& tbox); // place to display value void Show(); // display current value void Next(); // increment void Reset(); // get new value from user int Value(); // return current value ~Cycler(); }; 9

Similarities Between the Number and Cycler Classes Data: value : an internal integer value Text. Box* : a pointer to a Text. Box Code: Show. In Show Reset Value : provide Text. Box where value is displayed : display current value in Text. Box : use Text. Box to get new value from user : returns current internal value The Next() method is different! 10

Generalization-Specialization Hierarchy Base Class Name: Displayable Number Data: value, Text. Box* Code: Show. In Show Reset Value Derived Class Name: Counter Data: Code: Next Derived Class Name: Cycler Data: base Code: Next 11

Generalization-Specialization Hierarchy Name Shared Stuff Data Methods Name Data Methods 12

Logical Structure of a Cycler Object 13

Multiple Levels of Inheritance 14

An Inheritance Hierarchy of Displayable Numbers 15

Section 6. 3: Syntax of Inheritance class Displayable. Number { public: Displayable. Number(int init = 0); void Show. In(Text. Box& p); void Show(); void Reset(); int Value(); ~Displayable. Number(); }; // initial value zero // by default Base Class This is a complete class in and of itself and could have instances (objects) of it created. 16

Syntax of Inheritance (Continued) class Number : public Displayable. Number { public: Base Number(int init = 0); void Next(); Constructor ~Number(); }; Class Different, additional methods Destructor Derived Class 17

Syntax of Inheritance (Continued) class Cycler : public Displayable. Number { public: Ditto info Cycler(int b, int init = 0); void Next(); previous ~Cycler(); }; from slide public keyword Syntax Derived Class 18

Using Objects of Derived Classes Number count(10); Cycler binary(2); // initially 10 // base 2 Text. Box display(Location(10, 10), Shape(50, 50)); Text. Box onoff (Location(20, 20), Shape(50, 50)); count. Show. In(display); binary. Show. In(onoff); calling methods from base class count. Next(); binary. Next(); // increment by 1 modulo 2 count. Show(); binary. Show(); // display updated value int c = count. Value(); int b = binary. Value(); // get value of Number object // get value of Cycler object methods specific to the class 19

Example of the Protected Section private items are not accessible in derived classes class Displayable. Number { private: Text. Box* text. Box; // place to display value protected items are accessible in derived classes protected: int value; // internal counter anyone can see and manipulate public items public: Displayable. Number(int init); void Show. In(Text. Box& p); void Show(); void Reset(); int Value(); ~Displayable. Number(); }; // initial value // reply current value 20

A Complete Derived Class class Number : public Displayable. Number { public: What order are the Number(int init = 0); constructors done in? void Next(); ~Number(); Use the base }; class’s constructor Number: : Number(int init) : Displayable. Number(init) { } void Number: : Next() { value = value + 1; } Number: : ~Number() {} Not necessary if you just call the default (parameterless) constructor 21

A Complete Derived Class class Cycler : public Displayable. Number { private: int base; public: Cycler(int b, int init = 0); void Next(); ~Cycler(); }; additional initialization not in base class Cycler: : Cycler(int b, int init) : Displayable. Number(init) { base = b; } void Cycler: : Next() { value = (value + 1)%base; } can be done here “, base (b)” Cycler: : ~Cycler() {} 22

Order of Constructor Execution class Base { private: int value; public: Base(int init); }; class Derived : public Base { private: int base; public: Derived(int init, int b = 10); }; Base: : Base(int init) { cout << "Base Constructor " << init << endl; } Derived: : Derived(int b, int init): Base(init) { base = b; cout << "Derived Constructor " << b << endl; } 23

Order of Constructor Execution (cont’d) void main(){ Derived derived(8, 20); } Result: Base Constructor 20 Derived Constructor 8 24

Circle Class class Circle { private: Location center; int radius; Color draw. Color; Canvas *canvas; public: Circle(); void Display. In(Canvas& can); void Draw(); void Set. Color(Color color); void Change. Color(); int Xvalue(); int Yvalue(); int Get. Radius(); void Clear(Canvas& canvas); ~Circle(); }; 25

MCircle Class class MCircle: public Circle { private: Location direction; int resizespeed; int movespeed; public: MCircle(); void Resize(); void Move(); int Get. Resize. Speed(); int Set. Resize. Speed(); int Get. Move. Speed(); int Set. Move. Speed(); ~MCircle(); }; 26

Circle Class Revisited class Circle { private: Canvas *canvas; Color draw. Color; protected: int radius; Location center; public: Circle(); void Display. In(Canvas& can); void Draw(); void Set. Color(Color color); int Xvalue(); int Yvalue(); int Get. Radius(); void Clear(Canvas& canvas); ~Circle(); }; 27

Shape Base class? class Shape { private: Canvas *canvas; protected: Color draw. Color; Location center; public: Shape(); void Display. In(Canvas& can); void Set. Color(Color color); int Xvalue(); int Yvalue(); void Clear(Canvas& canvas); ~Shape(); }; We can’t draw it; is it useful? 28

Section 6. 4: Replacing Inherited Methods z. Problem: y. You have a base class. y. You’re writing a derived class. y. You don’t like a method in base class! y. You want to redefine method. z. Example: y. Displayable. Number: : Reset() reads text box; you want to reset to initial value! 29

Solution: Redefine Base Method z. In derived class, we must: y. Remember initial value to base class y. Re-define “Reset()” method z. Try writing derived class “Restart. Counter” now! 30

Here’s what we want. . . Name: Displayable Number Data: int value, Text. Box* Code: Show. In Show Value Reset() Name: Counter Data: Code: Next Implement this! Name: Restart Counter Data: int original Code: Reset() 31

Review. . . class Displayable. Number { private: Text. Box* text. Box; protected: int value; public: Displayable. Number(int init); void Show. In(Text. Box& p); void Show(); void Reset(); int Value(); }; // place to display value // internal counter // initial value // value = number in text. Box // reply current value class Number : public Displayable. Number { public: Number(int init = 0); void Next(); }; 32

Solution class Restart. Counter : public Number { private: int original; public: Restart. Counter(int init=0); void Reset() {value=original; } } Restart. Counter: : Restart. Counter(int init) : Number(init) {original=init; } 33

Invocation of Method is “Looked up” through layers 34

Section 6. 5: Extending Inherited Methods z. Problem: y. You have a base class. y. You’re writing a derived class. y. A method in base class is not quite ok. y. You want to extend method. z. Example: Last time: redefine y. Base Reset() reads text box; in class Cycler you want to insure number’s smaller than base! 35

Modify Cycler to Extend Reset() class Displayable. Number { private: Text. Box* text. Box; // place to display value protected: int value; // internal counter public: Displayable. Number(int init); void Show. In(Text. Box& p); void Show(); void Reset(); // value = number in text. Box int Value(); // reply current value }; class Cycler : public Displayable. Number { private: int base; public: Fill this in! Cycler(int base, int init = 0); void Next(); void Reset() { } }; 36

Modify Cycler to Extend Reset() class Displayable. Number { private: Text. Box* text. Box; // place to display value protected: int value; // internal counter public: Displayable. Number(int init); void Reset(); // value = number in text. Box }; class Cycler : public Displayable. Number { private: int base; public: Cycler(int base, int init = 0); void Next(); void Reset() { Displayable. Number: : Reset(); value = value % base; } }; 37

Moral of the Story z. Derived class can re-use method name from base class z. This replaces base method z. But derived class can also call base method, to extend base method. 38

Section 6. 6: Hiding Inherited Methods Let’s talk about a very serious problem. Sometimes a base method doesn’t make sense to a derived class. What do we do? 39

Example class Rectangle { public: void Set. Shape(Shape s); } class Square : public Rectangle { // inherits Set. Shape } You can reshape square into rectangle! 40

Solutions 1. Override base method so it’s harmless 2. Use private inheritance so base method isn’t visible 3. Revise the inheritance hierarchy Let’s look at all three. . . 41

Solution 1 a: Override base method void Square: : Set. Shape(Shape shape){} List pros and cons for this solution! 42

Solution 1 b: Override base method void Square: : Set. Shape(Shape shape) { Rectangle: : Set. Shape(shape. Width(), shape. Width()) ) } List pros and cons for this solution! 43

Solution 2: Use private inheritance class Square : public Rectangle {…} What does public, protected, private, or “nothing” mean here? What’s the effect of deleting “public”? What goes in the “…”? List pros and cons for this solution! 44

Solution 2: What goes in “…” class Square : public Rectangle { public: Square(int side); void Set. Side(int side); Rectangle: : Set. Location; Rectangle: : Draw; Rectangle: : Clear; Rectangle: : Rotate; } Write bodies of Constructor & Set. Side 45

Bodies of Constructor & Set. Side Square: : Square(int side) : Rectangle(Shape(side, side)) {} void Square: : Set. Side(int Side) { Set. Side(Shape(side, side)); } 46

Solution 3: Revise Inheritance Hierarchy Try writing class definitions for this… ? ? ? Square Rectangle Be sure you solve the Set. Size problem! 47

Answer. . . Quadrilateral Set. Location Draw Clear Rotate Note error in book’s diagram Square Rectangle Set. Side Set. Shape 48