1 / 108

Topics on Inheritance

Topics on Inheritance. Subtyping and Code Reuse Typing Conversions and Visibility Abstract Base Classes Multiple Inheritance Inheritance and Design Detailed C++ Considerations ##. Traits Passed Through Inheritance. But Mommy, where did my blue eyes come from?. 2.

Download Presentation

Topics on Inheritance

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Topics on Inheritance • Subtyping and Code Reuse • Typing Conversions and Visibility • Abstract Base Classes • Multiple Inheritance • Inheritance and Design • Detailed C++ Considerations ##

  2. Traits Passed Through Inheritance But Mommy, wheredid my blue eyescome from? 2

  3. The Inheritance Mechanism • Means of deriving new class from existing classes, called base classes • Reuses existing code eliminating tedious, error prone task of developing new code • Derived class developed from base by adding or altering code • Hierarchy of related types created that share code & interface ##

  4. Single and Multiple Inheritance Single inheritance occurs when single base class Multiple inheritance occurs when more thanone base class

  5. Credit Cards - Single Inheritance Same basic features Each is a little different

  6. Voice Mail - Multiple Inheritance Voice mail has featuresof both mail and phone

  7. Taxonomic Classification (1 of 3) Elephant and mouse both mammals • Descriptions succinct Root concept "mammal" • Warm-blooded • Higher vertebrates • Nourish young using milk-producing mammary glands

  8. Taxonomic Classification (2 of 3) Mammal Warm blooded Higher vertebrate Nourish young with milk-producing glands Mouse Elephant

  9. Taxonomic Classification (3 of 3) • In C++ terms, classes elephant and mouse derived from base class "mammal" • In OOP terms, elephant ISA mammal describes relationship • If circus had elephants, then object circus might have members of type elephant • Class circus HASA elephant describes subpart relationship ##

  10. Virtual Member Functions • Functions declared in base class and redefined in derived class • Class hierarchy defined by public inheritance creates related set of user types, all of whose objects may be pointed at by a base class pointer • By accessing virtual function through this pointer, C++ selects appropriate function definition at run-time ##

  11. Pure Polymorphism • Object being pointed at must carry around type information so distinction can be made dynamically • Feature typical of OOP code • Each object "knows" how it is acted on • Inheritance designed into software to maximize reuse and allow natural modeling of problem domain ##

  12. The OOP Design Methodology 1. Decide on an appropriate set of types 2. Design in their relatedness 3. Use inheritance to share code among classes

  13. A Derived Class • Class derived from an existing class • class classname:(public|protected|private)optbasename{ member declarations}; • Keyword class replaced by struct with members public by default • Keywords public, protected, and private used to specify how base class members are accessible to derived class ##

  14. Students and Graduate Students

  15. A Base Class: student • class student { • public: • enum year { fresh, soph, junior, senior, • grad }; • student(char* nm, int id, double g, • year x); • void print() const; • protected: • int student_id; • double gpa; • year y; • char name[30]; • };

  16. A Derived Class: grad_student • class grad_student : public student { • public: • enum support { ta, ra, fellowship, other }; • grad_student(char* nm, int id, double g, • year x, support t, char* d, char* th); • void print() const; • protected: • support s; • char dept[10]; • char thesis[80]; • };

  17. Inheriting from the Base Class • Derived class is modification of base class that inherits public and protected members of base class • In grad_student, student members are inherited • student_id gpa • name year • print##

  18. Add New Members in Derived Class • Derived class adds new members to existing class members • grad_student has three new data members and redefined member function • s • dept • thesis • print()##

  19. Benefits of Inheritance • Code is reused • grad_student uses tested code from student • Reflects relationship in problem domain • Special grouping grad student outgrowth of real world and treatment of this group • Polymorphic mechanisms allow client code to treat inherited class as subtype of base class • Simplifies code, maintains subtype distinctions##

  20. Public Inheritance (is a subtype) • Publicly inherited remain public • Private members can't be inherited • Protected members remain protected ## student shape grad_student ellipse polygon

  21. Private Inheritance (is not a subtype) • Public members become private • Protected members become private • Code reuse mechanism ## generic tree private string tree

  22. Typing Conversions and Visibility • Publicly derived class is subtype of base • Variable of derived class treated as if it were base class type • Pointer type pointer-to-base-class can point to objects of derived class type • Subtle implicit conversions occur between base and derived type • Difficult to follow what member is accessed if base and derived class overloaded same member name##

  23. Students and Graduate Students In many respects, they are the same, but in some they differ.

  24. More on the student Program (1 of 7) • student::student(char* nm, int id, double g, year x) • :student_id(id), gpa(g), y(x){ strcpy(name, nm);} • Constructor for base class does series of simple initializations • Calls strcpy() to copy student's name ##

  25. More on the student Program (2 of 7) • //publicly derived • grad_student::grad_student(char* nm, int id, double g, year x, support t, • char* d, char* th) • :student(nm, id, g, x), s(t) • { strcpy(dept, d); • strcpy(thesis, th); } • Constructor for student invoked as part of initializer list • Logically base class object needs to be constructed first before object can be completed • student_id and gpa are protected which makes them visible only to the derived class

  26. More on the student Program (3 of 7) • Reference to derived class may be implicitly converted to a reference to public base class • grad_student gs("Morris Pohl", 200, 3.2564, • grad, ta, "Pharmacy", "Retail Pharmacies"); • student& rs = gs; //alias • student* ps = &gs; //pointer init • Variable rs is reference to student • Base class of grad_student is student Reference conversion is appropriate

  27. More on the student Program (4 of 7) • void student::print() • { • cout << name << " , " << student_id • << " , " << y << " , " << gpa << endl; • } • void grad_student::print() • { • student::print(); //base class info • cout << dept << " , " << s << endl << thesis << endl; • } • Infinite loop if not scope-resolved student::print()

  28. More on the student Program (5 of 7) • #include "student.h" • main() //Test pointer conversion rules • { • student s("Mae Pohl", 100, 3.425, fresh), • *ps = &s; • grad_student gs("Morris Pohl",200, 3.2564, • grad, ta, "Pharmacy", • "Retail Pharmacies"), *pgs; • ps —> print(); //student::print • ps = pgs = &gs; • ps —> print(); //student::print • pgs —> print(); //grad_student::print • }

  29. More on the student Program (6 of 7) • main() declares both class variables and pointers to them • Conversion rule - pointer to publicly derived class may be converted implicitly to pointer to its base class • Pointer ps can point to objects of both classes, but pointer pgs can point only at objects of type grad_student##

  30. More on the student Program (7 of 7) • First ps -> print() invokes student::print • ps = pgs = &gs; both pointers pointing at object of type grad_student and assignment to ps involves implicit conversion • Second ps -> print(); invokes student::print • Irrelevant that pointer points at grad_student variable gs## • pgs -> print(); invokes grad_student::print • pgs is of type pointer to grad_student and, when invoked with an object of this type, selects a member function from this class

  31. Creating a New vect Class “We can rewrite this safe-array code to include a new vect_bnd class with dynamic bounds checking. We’ll use vect as a base class, and let vect_bnd use inheritance so we don’t have to repeat all the vect code. It’s basic functions serve our purposes exactly.”

  32. Dynamic Array Bounds (1 of 2) • Subscripting & assignment use these properties • Right side, lvalue automatically dereferenced • Left side specifies where value is stored • Safe array vect_bnd produced by deriving it from vect and invoking appropriate constructors • function-header : base-class-name (args)##

  33. Dynamic Array Bounds (2 of 2) • Safe array has constructors, destructor and overloaded subscripting operator • Constructors convert ordinary integer array to safe array by allocating sufficient memory • Upper and lower bounds checked • Subscript operator [] overloaded with function which tests for out-of-bounds condition on array access##

  34. Using Dynamic Array Bounds • Reuse code and extend vect type to safe array with dynamic bounds • More flexible and allows indices to correspond directly to problem domain • Example: Fahrenheit temperatures of water in its liquid state are is 32—212 degrees • Lower bound of 32 and upper bound of 212 • Safe array vect checked array bounds for in range and created arrays using free store##

  35. Dynamic Array Bounds (1 of 8) • class vect { • public: //constructors & destructor • vect(); //create a size 10 array • vect(int l); //create a size l array • vect(const vect& v); //init by vect • vect(int a[], int l); //init by array • ~vect() { delete [] p; } • int ub() const {return (size—1);} • int& operator[](int i); //range checked • vect& operator=(vect& v); • vect operator+(vect& v); • private: • int *p; //base pointer • int size; //number of elements • };

  36. Dynamic Array Bounds (2 of 8) • class vect_bnd: public vect { • public: • vect_bnd(); • vect_bnd(int, int); • int& operator[](int); • int ub() const { return (u_bnd); } //accessor • int lb() const { return (l_bnd); } • private: • int l_bnd, u_bnd; • }; • Derived type members l_bnd and u_bnd privately store lower and upper bounds

  37. Dynamic Array Bounds (3 of 8) • Derived type reuses base type's representation and code • Derived class constructors invoke base class constructors • Syntax is same as member initialization • function header: base—class—name(args)##

  38. Dynamic Array Bounds (4 of 8) • vect_bnd::vect_bnd() :vect(10) • { l_bnd = 0; • u_bnd = 9; • } • vect_bnd::vect_bnd(int lb, int ub) : • vect(ub — lb + 1) • { l_bnd = lb; • u_bnd = ub; • } • Additional code initializes bound's pair • Derived constructors call base constructors l_bnd u_bnd 0 1 2 3 4 5 6 7 8 9

  39. Dynamic Array Bounds (5 of 8) • Alternatively, could be done in initializing list • vect_bnd::vect_bnd(int lb, int ub) • vect(ub — lb + 1), l_bnd(lb), • u_bnd(ub) {}

  40. Dynamic Array Bounds (6 of 8) • int& vect_bnd::operator[](int i) • { • if (i < l_bnd || u_bnd < i) { • cerr << "index out of range" << endl; • exit(1); • } • return (vect::operator[](i — l_bnd)); • } • Reuse code in overloading indexing operator [] • Very inefficient - checking bounds twice

  41. Dynamic Array Bounds (7 of 8) • To avoid inefficient double bounds check, make two changes • First change access privilege of vect::p to protected so derived class has direct access to previously private implementation of vect • Allows us to make second change of using p in vect_bnd::operator[]()##

  42. Dynamic Array Bounds (8 of 8) • int& vect_bnd::operator[](int i) • { • if (i < l_bnd || u_bnd < i) { • cerr << "index out of range\n"; • exit(1); • }; • return (p[i — l_bnd]); • }

  43. Determining Access Privilege • Tradeoff in code reuse and efficiency • Inheritance requires thinking about three access boundaries • What is to be strictly private and what is to be protected depends on what is reusable ##

  44. Dynamic Virtual Function Selection • Typically base has virtual function and derived have their versions of function • Pointer to base class can point at either base or derived class objects • Member function selected depends on class of object being pointed at, not on pointer type • In absence of derived type member, base class virtual function used by default ##

  45. Virtual & Overloaded Function Selection • Overloaded member function is compile-time selected based on signature • It can have distinct return types • Once declared virtual, this property is carried along to all redefinitions in derived classes • virtual modifier not needed in derived functions##

  46. Virtual Function Selection (1 of 2) • #include <iostream.h> • class B { • public: • int i; • virtual void print_i() const { cout << i << " inside B" << endl; } • }; • class D: public B { //virtual too • public: • void print_i() const • { cout << i << " inside D" << endl; } • };

  47. 1 inside B 2 inside D Virtual Function Selection (2 of 2) • int main() • { • B b; • B* pb = &b; //point at a B object • D f; • f.i = 1 + (b.i = 1); • pb —> print_i(); //call B::print_i() • pb = &f; //point at a D object • pb —> print_i(); //call D::print_i() • }

  48. Comments on the virt Program • Different print_i() executed • Dynamically selected on object pointed at • "Object sent message print_i and selects its corresponding version of method" • Pointer's base type is not determining method (function) selection • Different class objects processed by different functions at run-time • ADTs, inheritance, and process of objects dynamically are essentials of OOP ##

  49. Confusion with Overloading (1 of 2) • Member function overloading and virtual functions cause mix-ups and confusion • class B { • public: • virtual foo(int); • virtual foo(double); • . . . • }; • class D: public B { • public: • foo(int); • . . . • };

  50. Confusion with Overloading (2 of 2) • main() • { • D d; • B b, *pb = &d; • b.foo(9.5); //selects B::foo(double); • d.foo(9.5); //selects D::foo(int); • pb —> foo(9.5); //B::foo(double); • } • Base class function B::foo(int) overriden in derived class • Base class function B::foo(double) hidden in derived class

More Related