0% found this document useful (0 votes)
85 views7 pages

11 - Inheritance1

This document provides an introduction to object-oriented programming inheritance concepts including derived classes, base classes, accessing base class members, derived class constructors, and overriding member functions. It explains that a derived class inherits all capabilities of the base class and can add its own functionality. An example class hierarchy is provided to demonstrate how a derived class extends a base class to add new functionality while retaining the original functionality. The key concepts of inheritance, including protected access specifiers and how base class members are accessed by derived classes, are described.

Uploaded by

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

11 - Inheritance1

This document provides an introduction to object-oriented programming inheritance concepts including derived classes, base classes, accessing base class members, derived class constructors, and overriding member functions. It explains that a derived class inherits all capabilities of the base class and can add its own functionality. An example class hierarchy is provided to demonstrate how a derived class extends a base class to add new functionality while retaining the original functionality. The key concepts of inheritance, including protected access specifiers and how base class members are accessed by derived classes, are described.

Uploaded by

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

AJ/Handout 11 -1- Object-Oriented Programming

Lesson 11
Objectives

 Introduction to Inheritance
 Derived Class and Base Class
 Accessing Base Class Members & protected Access Specifier
 Derived Class Constructors
 Overriding Member Functions
Introduction to Inheritance
Inheritance is the most powerful tool of Object Oriented Programming after classes themselves.
Inheritance is the process of creating new classes, called derived classes, from existing or base
classes. The base class inherits all the capabilities of base class and can add embellishment and
refinement of its own. The base class is unchanged by this process. It is an essential part of OOP.
Its big payoff is that it permits code reusability. Once base class is created and debugged then it
need not to touch again, however it can be adapted to work in different situations. It saves time and
money and increases program’s reliability.
Another important result of reusability is ease of distributing class libraries. You can use the
classes created by another programmer, without modifying it for suitable situations.

Derived Class and Base Class


Let us see an example for this discussion. We have discussed previously a class named as counter
which could simply increments count by one. Say that is a comprehensive class for that purpose
and now we need to do something more than that class let say decrement. Or that is a class which
basically deals with counting the people coming into and walking out from some bank. So that we
can count total number of people at any moment. Though we could do it by simply putting a
decrement operator but only for the instance we assume that we could not add something to base
class. Since it is quite common that a class which is working properly for one purpose may not
work that much efficient after adding some more functionality. Or we may not have access to the
source class.
#inlcude<iostream>
using namespace std;
class Counter
{
protected:
AJ/Handout 11 -2- Object-Oriented Programming

unsigned int count;


public:
Counter ( ) : count (0) {}
Counter (int c): count (c) {}
unsigned int get_count( ) const
{return count;}
Counter operator ++ ( )
{return Counter(count++);}
};
/////////////////////////////////////////
class Countdn : public Counter
{
Public:
Counter operator - - ( )
{return Counter(count- -);}
};
/////////////////////////
void main ( )
{
Countdn c1;

C1++, c1++, c1++;


Cout<<”c1=”<<c1.get_count( );

C1- -, c1- -;
Cout<<”c1=”<<c1.get_count( );
}
Here in this program we can see there is no need of a constructor of second class also “Countdn”
inherits all the features of “Counter” so we can use its member function. Also we have used some
new lines.
 Class Countdn : public Counter
Here we use a single colon instead of double colon the scope resolution operator, followed by the
keyword public and name of the base class “Counter”. This sets up the relation between two
classes. So this line say Countdn is derived from the base class Counter.
Accessing Base Class Members
AJ/Handout 11 -3- Object-Oriented Programming

An important topic in inheritance is knowing when a member function in the base class can be
used by objects of the derived class. This is called accessibility. Let us see how compiler handles
accessibility issue.
 Substituting Base Class Constructor
In the main( ) part of above class we created an object of class Countdn
Countdn c1;
This causes c1 to be created as an object of Countdn and initialized to 0. But how is it possible?
Since there is no constructor in derived class specifier. In fact this is by virtue of the base class, if
there is no constructor in derived class then it will automatically use the constructor of base class.
 Substituting Base Class Member Functions
The object of derived class Countdn also uses the operator ++ ( ) and get_count( ) from the base
class Counter. Again these functions are not available in derived class.
The protected Access Specifier
We have increased the functionality of a class without modifying it. The new specifier we have
seen is protected. First we see the case of private. A member function of a class can always access
class members, whether they are public or private. But any object declared externally can always
invoke (using dot operator) public members of the class. It is not allowed to use private members.
This is all we need to know if we don’t use inheritance. With inheritance, however, there are some
additional possibilities. Now question is that, can member function of derived class access
members of the base class? In other words, can operator - - ( ) in the Countdn access count in the
Counter? The answer is that only public or protected members of base class can be accessed by
member functions of derived class. Yet they can’t access private members. So protected is in
between public and private. Where is public is accessed anywhere, private is no where outside the
class, and protected is accessible within that class and the class derived from that class. This
insures that class in inheritance ready.
Dangers of protected
There are some drawbacks of protected specifier. Let you have created a class library, which you
have distributed to the public. Any programmer who buys this library can access easily the
protected members simply by deriving other classes from them. This made protected less secure
than private members. To avoid this situation it is safer to force the derived classes to only access
data from base classes using public functions in the base class. But using protected specifier leads
to simpler programming.
Base Class Unchanged
AJ/Handout 11 -4- Object-Oriented Programming

Throughout the process of inheritance base class remains unchanged. Also the base class and its
objects don’t know the anything about any classes derived from the base class. In above example
the object of base class can’t use operator - - ( ).
In some languages the base class is called super class and derived class in called sub class. Also
the base class is known as parent and derived class is known as child.

Derived Class Constructors


We have seen that an object of derived class was automatically initialized using no argument
constructor. What if we want to initialize it using one argument constructor of the base class. It will
not work. Since in previous case compiler will put the no argument constructor in derived class,
but no more constructors. For such a definition to work we must write a new set of constructor for
derived class. As shown below:
#inlcude<iostream>
using namespace std;
class Counter
{
protected:
unsigned int count;
public:
Counter ( ) : count (0) {}
Counter (int c): count (c) {}
unsigned int get_count( ) const
{return count;}
Counter operator ++ ( )
{return Counter(count++);}
};
/////////////////////////////////////////
class Countdn : public Counter
{
Public:
Countdn( ) : Counter (c) {}
Countdn(int c) : Counter (c) {}
Counter operator - - ( )
{return Counter(count- -);}
};
AJ/Handout 11 -5- Object-Oriented Programming

/////////////////////////

void main ( )
{
Countdn c1, c2(100);
Cout<<”c1=”<<c1.get_count( );
Cout<<”c2=”<<c2.get_count( );
C1++, c1++, c1++;
Cout<<”c1=”<<c1.get_count( );
c2- -, c2- -;
Cout<<”c2=”<<c2.get_count( );
Countdn c3=c2--;
Cout<<”c3=”<<c3.get_count( );
}
Here in this program we use two new constructors. Both have some unfamiliar feature ‘:’. This
construction causes the Countdn ( ) constructor to call Counter( ) in the base class. When the
object of Countdn is created it first call the Countdn( ) to initialize it. And it will in return call
Counter( ) which carries out the work.
Though it seems odd but it makes sense. You want to initialize any variable, whether they are in
derived class or base class before any statement in derived or base class constructors are executed.
By calling the base class constructor before the derived class constructors start to execute, we
accomplish this.

Overriding Member Functions


We can use the functions in the derived class that override—that is, they have the same name as
the functions of base class. You might want to do this so that calls in your program work the same
way for objects of both base and derived classes. Let us see this in example which deals with array
overflow and underflow control.
#include<iostream>
using namespace std;
#include<process.h> //for exit( )
class Stack
{
protected:
enum {MAX=3};
int top;
public:
Stack( )
AJ/Handout 11 -6- Object-Oriented Programming

{top = -1;}
void push(int var)
{st[++top] = var;}
int pop( )
{return st[top--];}
};
////////////////////////////////////////
class Stack2 : public Stack
{
public:
void push(int var) //put number on stack
{
if(top>=MAX-1)
{cout<<”Error: Stack is full”; exit(1);}
Stack : : push(var);
}
int pop( )
{
if(top<0)
{cout<<”Error: Stak is empty”; exit(1);}
return Stack : : pop( );
}
};
//////////////////////////////////////////
void main( )
{
Stack s1;
s1.push(11);
s1.push(22);
s1.push(33);
cout<<endl<<s1.pop( );
cout<<endl<<s1.pop( );
cout<<endl<<s1.pop( );
cout<<endl<<s1.pop( );
}
AJ/Handout 11 -7- Object-Oriented Programming

Which Function is used?


The Stack2 class contains two functions, push( ) and pop( ). These functions have the same names,
and the same argument and return types, as the functions in Stack. When we will call these
functions from main( ), in statement like
s1.push(11 );
How does the compiler know which function to use? Here is the rule: when the same function
exists in both the base class and the derived class, the function in the derived class will be
executed. (This is true of objects of the derived class. Objects of base class don’t know about the
functions in derived class so they will execute base class functions.)
In this situation we say that the derived class has overridden the functions of base class.
How do push( ) and pop( ) in the Stack2 access push( ) and pop( ) in the Stack? They use the scope
resolution operator, : :, like in the statements
Stack : : push(var);
return Stack : : pop( );
Without scope resolution operators, the compiler would think the local push( ) and pop( )
functions, which would lead to calling themselves and may lead to program failure.

You might also like