0% found this document useful (0 votes)
27 views60 pages

CSY2087 Inheritance

The document discusses key concepts in object-oriented programming, specifically focusing on object conversion, aggregation, inheritance, and polymorphism. It explains how classes can be related through 'has a' and 'is a' relationships, the importance of access specifiers, and the role of virtual functions in enabling dynamic binding. Additionally, it covers multiple inheritance and the challenges it presents, along with solutions for managing member function conflicts.

Uploaded by

imhailinh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views60 pages

CSY2087 Inheritance

The document discusses key concepts in object-oriented programming, specifically focusing on object conversion, aggregation, inheritance, and polymorphism. It explains how classes can be related through 'has a' and 'is a' relationships, the importance of access specifiers, and the role of virtual functions in enabling dynamic binding. Additionally, it covers multiple inheritance and the challenges it presents, along with solutions for managing member function conflicts.

Uploaded by

imhailinh
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 60

Data Structures and Algorithms

CSY2087
(Week 10)
14.6

Object Conversion
Object Conversion
• Type of an object can be converted to another type
• Automatically done for built-in data types
• Must write an operator function to perform conversion
• To convert an FeetInches object to an int:
FeetInches::operator int()
{return feet;}
• Assuming distance is a FeetInches object, allows
statements like:
int d = distance;

See Object Conversion: Program FeetInches Version 5


14.7

Aggregation
Aggregation

• Aggregation: a class is a member of a


class
• Supports the modeling of ‘has a’
relationship between classes – enclosing
class ‘has a’ enclosed class
• Same notation as for structures within
structures
Aggregation
class StudentInfo
{
private:
string firstName, LastName;
string address, city, state, zip;
...
};
class Student
{
private:
StudentInfo personalData;
...
};
See the Instructor, TextBook,
and Course classes.

See Program Pr14-15


What Is Inheritance?
What Is Inheritance?

• Provides a way to create a new class from


an existing class
• The new class is a specialized version of
the existing class
Example: Insects
The "is a" Relationship
• Inheritance establishes an "is a"
relationship between classes.
– A poodle is a dog
– A car is a vehicle
– A flower is a plant
– A football player is an athlete
Inheritance – Terminology
and Notation
• Base class (or parent) – inherited from
• Derived class (or child) – inherits from the base class
• Notation:
class Student // base class
{
. . .
};
class UnderGrad : public student
{ // derived class
. . .
};
Back to the ‘is a’ Relationship

• An object of a derived class 'is a(n)' object of


the base class
• Example:
– an UnderGrad is a Student
– a Mammal is an Animal

• A derived object has all of the characteristics of


the base class
What Does a Child Have?
An object of the derived class has:
• all members defined in child class
• all members declared in parent class

An object of the derived class can use:


• all public members defined in child class
• all public members defined in parent
class
• Example: GradedActivity Version 1
(Pr 15-2); Employ.cpp
Protected Members and
Class Access
Protected Members and
Class Access
• protected member access specification:
like private, but accessible by objects of
derived class

• Class access specification: determines


how private, protected, and public
members of base class are inherited by
the derived class
Class Access Specifiers

1) public – object of derived class can be


treated as object of base class (not vice-
versa)
2) protected – more restrictive than public,
but allows derived classes to know details of
parents
3) private – prevents objects of derived class
from being treated as objects of base class.
Example: GradedActivity Version 2 (Pr 15-3);
Pubpriv.cpp
Inheritance vs. Access
How inherited base class
members
Base class members appear in derived class
private: x private
x is inaccessible
protected: y base class
private: y
public: z private: z

private: x protected x is inaccessible


protected: y base class protected: y
public: z protected: z

private: x public x is inaccessible


protected: y base class protected: y
public: z public: z
More Inheritance vs.
Access
class Grade class Test : public Grade
private members: private members:
char letter; int numQuestions;
float score; float pointsEach;
void calcGrade(); int numMissed;
public members: public members:
void setScore(float); Test(int, int);
float getScore();
char getLetter();
private members:
int numQuestions:
When Test class inherits float pointsEach;
from Grade class using int numMissed;
public members:
public class access, it Test(int, int);
looks like this: void setScore(float);
float getScore();
char getLetter();
More Inheritance vs. Access
(2)
class Grade class Test : protected Grade
private members: private members:
char letter; int numQuestions;
float score; float pointsEach;
void calcGrade(); int numMissed;
public members: public members:
void setScore(float); Test(int, int);
float getScore();
char getLetter();
private members:
int numQuestions:
When Test class inherits float pointsEach;
from Grade class using int numMissed;
public members:
protected class access, it Test(int, int);
looks like this: protected members:
void setScore(float);
float getScore();
char getLetter();
More Inheritance vs. Access
(3)
class Grade class Test : private Grade
private members: private members:
char letter; int numQuestions;
float score; float pointsEach;
void calcGrade(); int numMissed;
public members: public members:
void setScore(float); Test(int, int);
float getScore();
char getLetter();
private members:
int numQuestions:
When Test class inherits float pointsEach;
from Grade class using int numMissed;
private class access, it void setScore(float);
float getScore();
looks like this: char getLetter();
public members:
Test(int, int);
Constructors and
Destructors in Base and
Derived Classes
Constructors and Destructors
in Base and Derived Classes
• Derived classes can have their own
constructors and destructors
• When an object of a derived class is
created, the base class’s constructor is
executed first, followed by the derived
class’s constructor
• When an object of a derived class is
destroyed, its destructor is called first, then
that of the base class
Constructors and Destructors
in Base and Derived Classes
Program 5-14 (Continued)
Passing Arguments to
Base Class Constructor
• Allows selection between multiple base
class constructors
• Specify arguments to base constructor on
derived constructor heading:
Square::Square(int side) :
Rectangle(side, side)
• Can also be done with inline constructors
• Must be done if base class has no default
constructor
• Example: Pr 15-5, Cube.h, Rectangle.h
Passing Arguments to
Base Class Constructor

derived class constructor base class constructor

Square::Square(int side):Rectangle(side,side)

derived constructor base constructor


parameter parameters
Redefining Base Class
Functions
Redefining Base Class
Functions
• Redefining function: function in a derived
class that has the same name and
parameter list as a function in the base
class

• Typically used to replace a function in base


class with different actions in derived class
Redefining Base Class
Functions
• Not the same as overloading – with
overloading, parameter lists must be
different

• Objects of base class use base class


version of function; objects of derived
class use derived class version of function
• Example: Pr15-7, Pr15 -8
Base Class

Note setScore function


Derived Class

Redefined setScore function


From Program 15-7
Problem with Redefining
• Consider this situation:
– Class BaseClass defines functions x() and y().
x() calls y().
– Class DerivedClass inherits from BaseClass and
redefines function y().
– An object D of class DerivedClass is created and
function x() is called.
– When x() is called, which y() is used, the one
defined in BaseClass or the the redefined one in
DerivedClass?
Problem with Redefining
BaseClass

void X(); Object D invokes function X()


void Y(); In BaseClass. Function X()
invokes function Y() in BaseClass, not
DerivedClass function Y() in DerivedClass,
because function calls are bound at
compile time. This is static
binding.

void Y();

DerivedClass D;
D.X();
Class Hierarchies
Class Hierarchies
• A base class can be derived from another
base class.
Class Hierarchies
• Consider the GradedActivity, FinalExam,
PassFailActivity, PassFailExam hierarchy in
Pr15-9.
Polymorphism and Virtual
Member Functions
Polymorphism and
Virtual Member Functions

• Virtual member function: function in base class that expects to be


redefined in derived class
• Function defined with key word virtual:
virtual void Y() {...}
• Supports dynamic binding: functions bound at run time to function
that they call
• Without virtual member functions, C++ uses static (compile time)
binding
Consider this function (from Program 15-10)

Because the parameter in the displayGrade function is a GradedActivity


reference variable, it can reference any object that is derived from
GradedActivity. That means we can pass a GradedActivity object, a
FinalExam object, a PassFailExam object, or any other object that is
derived from GradedActivity.

A problem occurs in Program 15-10 and Graded Activity Version2


however...
As you can see from the example output, the getLetterGrade member
function returned ‘C’ instead of ‘P’. This is because the GradedActivity
class’s getLetterGrade function was executed instead of the
PassFailActivity class’s version of the function.
Static Binding
• Program 15-10 displays 'C' instead of 'P'
because the call to the getLetterGrade
function is statically bound (at compile
time) with the GradedActivityclass's
version 2 of the function.

• We can remedy this by making the


function virtual.
Virtual Functions
• A virtual function is dynamically bound to
calls at runtime.

• At runtime, C++ determines the type of


object making the call, and binds the
function to the appropriate version of the
function.
• See: VirtualExample.cpp
Virtual Functions
• To make a function virtual, place the
virtual key word before the return type in
the base class's declaration:

virtual char getLetterGrade() const;


• The compiler will not bind the function to
calls. Instead, the program will bind them
at runtime.
Updated Version of GradedActivity

The function
is now virtual.

The function also becomes


virtual in all derived classes
automatically!
Programs 15-11 and GradedActivity Version 3 rectify the
problem by making function virtual

This type of behavior is known as polymorphism. The term


polymorphism means the ability to take many forms.

Programs 15-12 and GradedActivity Version 3 demonstrates


polymorphism by passing
objects of the GradedActivity and PassFailExam classes to the
displayGrade function.
Polymorphism Requires
References or Pointers
• Polymorphic behavior is only possible
when an object is referenced by a
reference variable or a pointer (Pr
15-13), as demonstrated in the
displayGrade function.
Base Class Pointers
• Can define a pointer to a base class object
• Can assign it the address of a derived
class object
Base Class Pointers
• Base class pointers and references only know
about members of the base class
– So, you can’t use a base class pointer to call a
derived class function

• Redefined functions in derived class will be


ignored unless base class declares the function
virtual
Redefining vs. Overriding
• In C++, redefined functions are statically
bound and overridden functions are
dynamically bound.

• So, a virtual function is overridden, and a


non-virtual function is redefined.

• See Program 15-14 for an example


Virtual Destructors
• It's a good idea to make destructors virtual
if the class could ever become a base
class.
• Otherwise, the compiler will perform static
binding on the destructor if the class ever
is derived from.
• See Program 15-15 and Program 15-16
for examples
Multiple Inheritance
Multiple Inheritance
• A derived class can have more than one base
class
• Example: Engmult.cpp
• Each base class can have its own access
specification in derived class's definition:
class cube : public square,
public rectSolid;
class class
square rectSolid

class
cube
Multiple Inheritance
• Arguments can be passed to both base
classes' constructors:
cube::cube(int side) :
square(side),
rectSolid(side, side, side);
• Base class constructors are called in order
given in class declaration, not in order
used in class constructor
Multiple Inheritance

• Problem: what if base classes have member


variables/functions with the same name?
• Solutions:
– Derived class redefines the multiply-defined function
– Derived class invokes member function in a particular
base class using scope resolution operator ::
• Compiler errors occur if derived class uses base
class function without one of these solutions
• See Ambigu; Date, Time, DateTime and Program
15-18 for examples

You might also like