1 9. OOP & ADTs: Introduction to Inheritance Read Chap. 12 A. Inheritance, OOD, and OOP (§12.1 & 12.2) A major objective of OOP: writing reusable code.

Slides:



Advertisements
Similar presentations
CPA: C++ Polymorphism Copyright © 2007 Mohamed Iqbal Pallipurath Overview of C++ Polymorphism Two main kinds of types in C++: native and user-defined –User-defined.
Advertisements

1 l Inheritance Basics l Programming with Inheritance l Dynamic Binding and Polymorphism Inheritance.
C++ How to Program, 7/e © by Pearson Education, Inc. All Rights Reserved.
Comp 249 Programming Methodology Chapter 7 - Inheritance – Part A Dr. Aiman Hanna Department of Computer Science & Software Engineering Concordia University,
Inheritance Inheritance Reserved word protected Reserved word super
Classes and Object- Oriented... tMyn1 Classes and Object-Oriented Programming The essence of object-oriented programming is that you write programs in.
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
© Copyright Eliyahu Brutman Programming Techniques Course Version 1.0.
OOP in Java Nelson Padua-Perez Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
1 Chapter 7 l Inheritance Basics l Programming with Inheritance l Dynamic Binding and Polymorphism Inheritance.
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson Education, Inc. All rights reserved Inheritance.
Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson Education, Inc. All rights reserved OOP and.
C++ fundamentals.
CSCI-383 Object-Oriented Programming & Design Lecture 15.
Inheritance. © 2004 Pearson Addison-Wesley. All rights reserved 8-2 Inheritance Inheritance is a fundamental object-oriented design technique used to.
Computer Science and Software Engineering University of Wisconsin - Platteville 7. Inheritance and Polymorphism Yan Shi CS/SE 2630 Lecture Notes.
OOP Languages: Java vs C++
CSM-Java Programming-I Spring,2005 Introduction to Objects and Classes Lesson - 1.
Chapter 12: Adding Functionality to Your Classes.
C++ Programming: Program Design Including Data Structures, Fourth Edition Chapter 13: Pointers, Classes, Virtual Functions, and Abstract Classes.
Pointer Data Type and Pointer Variables
Learners Support Publications Pointers, Virtual Functions and Polymorphism.
C++ Programming: From Problem Analysis to Program Design, Fourth Edition Chapter 14: Pointers, Classes, Virtual Functions, and Abstract Classes.
MT311 Java Application Development and Programming Languages Li Tak Sing( 李德成 )
CISC6795: Spring Object-Oriented Programming: Polymorphism.
1 Understanding Inheritance COSC 156 C++ Programming Lecture 8.
Object Orientation Yaodong Bi, Ph.D. Department of Computer Sciences University of Scranton October 18, 2015October 18, 2015October 18, 2015.
Inheritance - Polymorphism ITI 1121 Nour El Kadri.
1 Inheritance. 2 Why use inheritance?  The most important aspect of inheritance is that it expresses a relationship between the new class and the base.
Copyright © 2007 Pearson Education, Inc. Publishing as Pearson Addison-Wesley. Ver Chapter 8: Class Relationships Data Abstraction & Problem Solving.
Data Structures Using C++ 2E1 Inheritance An “is-a” relationship –Example: “every employee is a person” Allows new class creation from existing classes.
Chapter 12: Pointers, Classes, Virtual Functions, and Abstract Classes.
Design.ppt1 Top-down designs: 1. Define the Problem IPO 2. Identify tasks, Modularize 3. Use structure chart 4. Pseudocode for Mainline 5. Construct pseudocode.
JAVA: An Introduction to Problem Solving & Programming, 5 th Ed. By Walter Savitch and Frank Carrano. ISBN © 2008 Pearson Education, Inc., Upper.
Chapter 3 Inheritance and Polymorphism Goals: 1.Superclasses and subclasses 2.Inheritance Hierarchy 3.Polymorphism 4.Type Compatibility 5.Abstract Classes.
Object Oriented Software Development
Chapter 7 Understanding Inheritance. LOGO Objectives  Learn about inheritance and its benefits  Create a derived class  Learn about restrictions imposed.
Simple Classes. ADTs A specification for a real world data item –defines types and valid ranges –defines valid operations on the data. Specification is.
Introduction to c++ programming - object oriented programming concepts - Structured Vs OOP. Classes and objects - class definition - Objects - class scope.
Lecture 10 Concepts of Programming Languages Arne Kutzner Hanyang University / Seoul Korea.
Inheritance. Inheritance - Introduction Idea behind is to create new classes that are built on existing classes – you reuse the methods and fields and.
Object-Oriented Programming Chapter Chapter
Advanced C++ Topics Chapter 8. CS 308 2Chapter 8 -- Advanced C++ Topics This chapter describes techniques that make collections of reusable software components.
Foundations: Language mechanisms and primitive OO concepts Lecture 1: Classification and Inheritance Michigan State University Spring 2008 E. Kraemer Notes.
Inheritance CSI 1101 Nour El Kadri. OOP  We have seen that object-oriented programming (OOP) helps organizing and maintaining large software systems.
Inheritance Initialization & Destruction of Derived Objects Protected Members Non-public Inheritance Virtual Function Implementation Virtual Destructors.
Coming up: Inheritance
1 Inheritance Reserved word protected Reserved word super Overriding methods Class Hierarchies Reading for this lecture: L&L 9.1 – 9.4.
1 Classes II Chapter 7 2 Introduction Continued study of –classes –data abstraction Prepare for operator overloading in next chapter Work with strings.
Inheritance and Class Hierarchies Chapter 3. Chapter 3: Inheritance and Class Hierarchies2 Chapter Objectives To understand inheritance and how it facilitates.
Inheritance and Class Hierarchies Chapter 3. Chapter Objectives  To understand inheritance and how it facilitates code reuse  To understand how Java.
Classes, Interfaces and Packages
Overview of C++ Polymorphism
1 9. OOP & ADTs: Introduction to Inheritance Read Chap. 12 A. Inheritance, OOD, and OOP (§12.1 & 12.2) A major objective of OOP: ______________________________.
Programming Fundamentals1 Chapter 7 INTRODUCTION TO CLASSES.
 Description of Inheritance  Base Class Object  Subclass, Subtype, and Substitutability  Forms of Inheritance  Modifiers and Inheritance  The Benefits.
Structure A Data structure is a collection of variable which can be same or different types. You can refer to a structure as a single variable, and to.
Chapter 12: Pointers, Classes, Virtual Functions, Abstract Classes, and Lists.
1 Inheritance One of the goals of object oriented programming is code reuse. Inheritance is one mechanism for accomplishing code reuse. It allows us to.
Inheritance Modern object-oriented (OO) programming languages provide 3 capabilities: encapsulation inheritance polymorphism which can improve the design,
7. Inheritance and Polymorphism
Andy Wang Object Oriented Programming in C++ COP 3330
Review: Two Programming Paradigms
Object Orientation Yaodong Bi, Ph.D. Department of Computer Sciences
Understanding Inheritance
Inheritance Basics Programming with Inheritance
OOP and ADTs Chapter 14 Nyhoff, ADTs, Data Structures and Problem Solving with C++, Second Edition, © 2005 Pearson Education, Inc. All rights reserved.
Java Programming Language
Computer Programming with JAVA
Overview of C++ Polymorphism
Presentation transcript:

1 9. OOP & ADTs: Introduction to Inheritance Read Chap. 12 A. Inheritance, OOD, and OOP (§12.1 & 12.2) A major objective of OOP: writing reusable code (to avoid re-inventing the wheel). Ways to do this in C++:  Encapsulate code within functions  Build classes  Store classes and functions in separately-compiled libraries  Convert functions into type-parameterized function templates  Convert classes into type-parameterized class templates An additional approach that distinguishes OOP from the others:  Inheritance: Define one class (derived class) in terms of another (base) class, reusing the data members and function members of the base class.

2 Example: Suppose a problem requires stack operations not provided in our stack class — e.g., max(), min() Ways to Approach this: #1: Add function members to the Stack class that implement the new operations. Bad: This can easily mess up a tested, operational class, creating problems for other client programs. new operations push(), pop(),... myTop,... new data members Stack class

3 #2: An adapter approach: Build a new RevStack class that contains a Stack as a data member. Better, but: A RevStack is not a Stack ; it has a Stack. new operations including revised push(), pop(),... new data members RevStack class push(), pop(),... myTop,... Stack stObj

4 #3: Copy-&-paste approach: Build a new RevStack class, copying and pasting the data members and function members of Stack into RevStack. Almost right, but: These are separate independent classes. Modifying Stack (e.g., changing from an array to a linked list for the stack elements) doesn't automatically update a RevStack. new operations new data members RevStack class push(), pop(),... myTop,... push(), pop(),... myTop,... Stack class copy

5 (iii) Mistakes made in building RevStack class will be local to it; the original Stack class remains unchanged and client programs are not affected. #4: Object-oriented approach: Derive a new class RevStack from the Stack class, which is called its parent class or base class. This is the best: (i) A derived class inherits all members of its parent class (including its operations); we need not reinvent the wheel. (ii)Modifying the Stack class automatically updates the RevStack class.

6 Object-oriented design (OOD) is to engineer one’s software as follows: 1. Identify the objects in the problem 2. Look for commonality in those objects 3. Define base classes containing that commonality 4. Define derived classes that inherit from the base class These last two steps are the most difficult aspects of OOD. Object-oriented programming (OOP) was first used to describe the programming environment for Smalltalk, the earliest true object- oriented programming language. OOP languages have three important properties:  Encapsulation We've done this  Inheritance  Polymorphism, with the related concept of dynamic or late binding

7 B. Derived Classes Problem: Model various kinds of licenses. Old Approach: Build separate classes for each license from scratch OOD: What attributes do all licenses have in common? Then store these common attributes in a general (base) class License : class License { public: // Function members Display(), Read(),... private: // we'll change this in a minute long myNumber; string myLastName, myFirstName; char myMiddleInitial; int myAge; Date myBirthDay; // Date is a user-defined type... };

8 We could include a data member of type License in each of the classes for the various kinds of licenses and then add new members: class DriversLicense { public:... private: License common; int myVehicleType; string myRestrictionsCode;... }; class HuntingLicense { public:... private: License common; string thePrey; Date seasonBegin, seasonEnd;... }; class PetLicense { public:... private: License common; string myAnimalType;... }; This has-a relation (inclusion) defines containment; i.e., when one object contains an instance of another object.

9 This inclusion technique works but it is a bit "clunky" and inefficient; for example, we need to "double dot" to access members of the included object: DriversLicense h;... h.common.Display(cout); Worse... Can one say that a driver’s license is a license? No! This is bad OOD. Design should reflect reality not implementation. What we really want is the is-a relationship because a driver’s license is a license

10 So we need: a DriversLicense is a License, not a DriversLicense has a License.  we need inheritance. We will derive the specialized license classes from the base class License and add new members to store and operate on their new attributes. Problem: Private class members cannot be accessed outside of their class (except by friend functions), not even within derived classes.

11 class License { public: // Function members // Display(), Read(),... protected: long myNumber; string myLastName, myFirstName; char myMiddleInitial; int myAge; Date myBirthDay;... }; One C++ solution: Members declared to be protected: can be accessed within a derived class, but remain inaccessible to programs or non-derived classes that use the class (except for friend functions). So change the private section in class License to a protected section:

12 Now we can derive classes for the more specialized licenses from License : c lass DriversLicense : public License { public:... protected: int myVehicleType; string myRestrictionsCode;... }; c lass HuntingLicense : public License { public:... protected: string thePrey; Date seasonBegin, seasonEnd;... }; c lass PetLicense : public License { public:... protected: string myAnimalType;... };

13 Classes like DriversLicense, HuntingLicense, and PetLicense are said to be derived classes (or child classes or subclasses), and the class License from which they are derived is called a base class (or parent class or superclass). We have used protected sections rather than private ones in these derived classes to make it possible to derive "second-level" classes from these if/when it becomes necessary; for example: class MooseLicense : public HuntingLicense { public:... protected: int theAntlerMaximum; int theBullwinkleFactor;... };

14 This leads to class hierarchies — usually pictured as a tree but with arrows drawn from a derived class to its base class: Each non-root class inherits the members of its ancestor classes. This means that an attribute needs to be defined only once (at the appropriate level), allowing a programmer to reuse the (one) definition many times. Java API

15 Usual Form of Declaration of a Derived Class DerivedClassName : public BaseClassName {... // new data members and // functions for derived class... } (More generally, the keyword public can be replaced by private or protected.)

16 The Fundamental Property of Derived Classes They inherit the members of the base class (and thus the members of all ancestor classes). Other Properties:  They cannot access private members of the base class.  Access to public and protected members of the base class depends on the kind of inheritance specified in the heading: public  public and protected, respectively private  private protected  protected

17 The most common is public inheritance; this is the only kind we will use. It means that:  We can use the public and protected members of the base class in a derived class just as though they were declared in the derived class itself. It gives rise to the is-a relationship: For class Derived : public Base { //... members of Derived... }; every Derived object is a Base object. For example: A HuntingLicense is a License A MooseLicense is a HuntingLicense A MooseLicense is a License

18 The property that derived classes inherit the members of ancestor classes can easily be misused. For example, it is bad design to do the following just to get the members of one class into another: class BusDriver : public License {... } Rather, we should use: class BusDriver {... private: License myLicense;// a bus driver has a license... }; Design Principle: Don't use public inheritance for the has-a relationship.

19 A third relationship between classes is the uses relationship: One class might simply use another class. For example, a Fee() member function in a LicensePlate class might have a parameter of type DriversLicense. But this class simply uses the DriversLicense class — it is not a DriversLicense and it does not have a DriversLicense. It isn't always easy to tell which is the appropriate one to use. Two useful tests in deciding whether to derive Y from X: 1. Do the operations in X behave properly in Y? 2. (The "need-a use-a" test): If all you need is a Y, can you use an X?

20 Summary: The OOP approach to system design is to: 1. Carefully analyze the objects in a problem from the bottom up. 2. Where commonality exists between objects, group the common attributes into a base class:

21 3. Then repeat this approach “upwards” as appropriate:

22 Once no more commonality exists, OO implementation then: 4. Proceeds from the top down, building the most general base class(es): 5. The less-general classes are then derived (publicly) from that base class(es):

23 6. Derivations continue until classes for the actual objects in the system are built: 7. These classes can then be used to construct the system’s objects.

24 C. Another (Classic) Example: Employees Problem: Design a payroll system. Following the four OOD steps, we proceed as follows: 1. Identify the objects in the problem: Salaried employees Hourly employees 2. Look for commonality in those objects: what attributes do they share? Id number Name Department...

25 3. Define a base class containing the common data members: class Employee { public: //... various Employee operations... protected: long myIdNum; // Employee's id number string myLastName, // " last name myFirstName; // " first name char myMiddleInitial; // " middle initial int myDeptCode; // " department code //... other members common to all Employees };

26 4. From the base class, derive classes containing special attributes: a.A salaried employee class: class SalariedEmployee : public Employee { public: //... salaried employee operations... protected: double mySalary; }; b. An hourly employee class: class HourlyEmployee : public Employee { public: //... hourly employee operations... protected: double myWeeklyWage, myHoursWorked, myOverTimeFactor; };

27 and others... Employee Commissione d Employee Contract Employee Salaried Employee Hourly Employee Manager Pro- grammer Sales Reviewer Editor Execu- tive Super- visor Consul- tant Secre- tary Tech Support

28 All of the classes that have Employee as an ancestor inherit the members (data and function) of Employee. For example, each HourlyEmployee and Manager object is an Employee object so each contains the members myIdNum, myLastName, myFirstName, and so on... So, if Employee has a public operation to extract myIdNum, long IdNumber() const { return myIdNum; } then it can be used by hourly employees and managers: HourlyEmployee hourlyEmp; Manager managerEmp;... cout << hourlyEmp.IdNumber() << endl << managerEmp.IdNumber() << endl;

29 Reusability : Suppose we define an output function member in Employee : void Employee::Print(ostream & out) const { out << myIdNum << ' ' << myLastName << ", " << myFirstName << ' ' << myMiddleNInitial << " " << myDeptCode << endl; } In derived classes, we can override Print() with new definitions that reuse the Print() function of class Employee. A class Deriv derived from class Base can call Base::F() to reuse the work of the member function F() from the base class. Not "overload"

30 void HourlyEmployee::Print(ostream & out) const { Employee::Print(out); //inherited members out << "$" << myWeeklyWage << endl //local members << myHoursWorked << endl << myOverTimeFactor << endl; } For example: void SalariedEmployee::Print(ostream & out) const { Employee::Print(out); //inherited members out << "$" << mySalary << endl;//local members }

31 Is-a and Has-a Relationships : An object can participate in is-a and has-a relationships simultaneously. For example, we could define an address class class Address { public: string street, city, state, zip; } and use it to declare some data member in the class Employee. Then, for example, a SalariedEmployee is-an Employee and has-an Address. Skip?

32 Constructors and Inheritance Consider Employee 's constructor // Explicit-Value Constructor inline Employee::Employee(long id, string last, string first, char initial, int dept) { myIdNum = id; myLastName = last; myFirstName = first; myMiddleInitial = initial; myDeptCode = dept; } A derived class can use a member-initialization-list to call the base-class constructor to initialize the inherited data members — easier than writing it from scratch.

33 // Definition of SalariedEmployee explicit-value constructor inline SalariedEmployee::SalariedEmployee (long id, string last, string first, char initial, int dept, double sal) From the derived class constructor, pass the id number, last name, first name, middle initial and dept. code to the Employee constructor to initialize those members. { mySalary = sal; } SalariedEmployee() then initializes only its own (local) member(s). : Employee(id, last, first, initial, dept)

34 General form of Member-Initialization-List Mechanism: Derive::Derive(ParameterList) : Base(ArgList) { // initialize the non-inherited members // in the usual manner... } Initializations in a member-initialization-list are done first, before those in the body of the constructor function. General Principle of Derived Class Initialization Use the base class constructor to initialize base class members, and use the derived class constructor to initialize derived class members.

35 Member-initialization list can also be used to initialize new data members in the derived class: Data member datamem of a derived class can be initialized to an initial value initval using the unusual function notation datamem(initval) in the member-initialization list. Example: inline SalariedEmployee::SalariedEmployee (long id, string last, string first, char initial, int dept, double sal) : Employee(id, last, first, initial, dept) { } This is less commonly used than "normal" initialization datamem = initval; in the function body. It is used when initialization is desired before the constructor fires., mySalary(sal)

36 D. Polymorphism Consider: class Employee { public: Employee(long id = 0, string last = "", string first = "", char initial = ' ', int dept = 0); void Print(ostream & out) const; //... other Employee operations... protected: //... data members common to all Employees }; // Definition of Print void Employee::Print(ostream & out) const {... } // Definition of output operator<< ostream & operator<<(ostream & out, const Employee & emp) { emp.Print(out); return out; }

37 And suppose we have overridden Print() for the subclasses SalariedEmployee and HourlyEmployee as described earlier. The statements: Employee emp(11111, "Doe", "John", 'J', 11); SalariedEmployee empSal(22222, "Smith", "Mary", 'M', 22, 59900); HourlyEmployee empHr(33333, "Jones", "Jay", 'J', 33, 15.25, 40); cout << emp << endl << empSal << endl << empHr << endl; then produce as output: not: Doe, John J Smith, Mary M 22 $ Jones, Jay J 33 $ Doe, John J Smith, Mary M Jones, Jay J 33

38 This is because the call to Print() in the definition of operator<<() uses Employee 's Print(). What we need is dynamic or late binding: Don't bind a definition of a function member to a call to that function until runtime. This is accomplished by declaring Print() to be a virtual function by prepending the keyword virtual to its prototype in the Employee class: class Employee { public: //... virtual void Print(ostream & out) const; //... other Employee operations... private: //... data members common to all Employees };

39 This works; operator<<() will use Employee::Print() for Employee s SalariedEmployee::Print() for SalariedEmployee s HourlyEmployee::Print() for HourlyEmployee s The same function call can cause different effects at different times — has many forms — based on the function to which the call is bound. Such calls are described as polymorphic (Greek for "many forms"). Polymorphism is another important advantage of inheritance in OOP languages. Thanks to polymorphism, we can apply operator<<() to derived class objects without explicitly overloading it for those objects. Note: This is a good reason to define operator<<() so that it calls some output function member of a class rather than making it a friend function.

40 Another Example: A base-class pointer can point to any derived class object. So consider a declaration Employee * eptr; Since a SalariedEmployee is-an Employee, eptr can point to a SalariedEmployee object: eptr = new SalariedEmployee; Similarly, it can point to an HourlyEmployee object: eptr = new HourlyEmployee; For the call eptr->Print(cout); to work, SalariedEmployee::Print(cout) must be used when eptr points to a SalariedEmployee, but HourlyEmployee:: Print(cout) must be used when eptr points to HourlyEmployee. Here is another instance where Print() must be a virtual function so that this function call can be bound to different function definitions at different times. 

41 By declaring a base-class function member to be virtual, a derived class can override that function so that calls to it though a pointer or reference will be bound (at run-time) to the appropriate definition. If we want to force derived classes to provide definitions of some virtual function, we make it a pure virtual function — also called an abstract function — and the class is called an abstract class. This is accomplished in C++ by attaching = 0 to the function's prototype: virtual PrototypeOfFunction = 0; No definition of the function is given in the base class. Classes derived from it must provide a definition.

42 E. Hetergeneous Data Structures Consider a LinkedList of Employee objects: LinkedList L; Each node of L will only have space for an Employee, with no space for the additional data of an hourly or salaried employee: Such a list is a homogeneous structure: Each value in the list must be of the same type ( Employee ).

43 Now suppose we make L a LinkedList of Employee pointers: LinkedList L; Then each node of L can store a pointer to any object derived from class Employee : Thus, salaried and hourly employees can be intermixed in the same list, and we have a heterogeneous storage structure. Employee SalariedEmployee HourlyEmployee

44 Now consider: Node * nPtr = L.first; while (nPtr != 0) { nptr->data->Print(cout); nptr = nPtr->next; } For the call nPtr->data->Print(cout); to work when nPtr->data points to a SalariedEmployee object, SalariedEmployee::Print() within that object must be called; but when nPtr->data is a pointer to an HourlyEmployee, HourlyEmployee::Print() within that object must be called. Here is another instance where Print() must be a virtual function.