0% found this document useful (0 votes)
18 views53 pages

Module 3 - BTCSE30218M3

The document discusses Object-Oriented Programming, specifically focusing on inheritance, which allows the creation of new classes from existing ones. It outlines various types of inheritance, such as single, multilevel, multiple, hierarchical, and hybrid inheritance, along with their advantages and implementation in C++. Additionally, it covers concepts like access specifiers, constructors, destructors, and the diamond problem in inheritance.

Uploaded by

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

Module 3 - BTCSE30218M3

The document discusses Object-Oriented Programming, specifically focusing on inheritance, which allows the creation of new classes from existing ones. It outlines various types of inheritance, such as single, multilevel, multiple, hierarchical, and hybrid inheritance, along with their advantages and implementation in C++. Additionally, it covers concepts like access specifiers, constructors, destructors, and the diamond problem in inheritance.

Uploaded by

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

Object Oriented

Programming

Modulue-3 Inheritance

BTCSE302-18
Base Class

 A base class is the fundamental class from which other classes derive.

 It encapsulates the common attributes and methods that can be shared by derived classes,
promoting code reusability and hierarchical classification.

 Provides the foundation for polymorphism and encapsulation in object-oriented


programming.
3
INHERITANCE

It is the Process of creating a New class from an existing class. The Existing class is called Base or
Parent class. The New class is called as Child or Derived Class.
Advantages
 It permits code reusability. So, save time and increase the program reliability.
 A programmer can use a class created by another person or company without modifying it derive
other classes from it that are suited to particular situations
 Improve Program Reliability
 It Permits code sharing
 The base class need not be changed but can be adapted to suit the requirements in different
applications.
4
INHERITANCE

It is the Process of creating a New class from an existing class. The Existing class is called Base or
Parent class. The New class is called as Child or Derived Class.

Base/Sub Class Derived/Super class


Methods Base class methods
and +
Properties Additional methods
5
WHY AND WHEN TO USE INHERITANCE?

 Consider a group of vehicles. You need to create classes for Bus, Car and Truck. The methods
fuelAmount(), capacity(), applyBrakes() will be same for all of the three classes. If we create
these classes avoiding inheritance then we have to write all of these functions in each of the
three classes as shown in below figure:
6
WHY AND WHEN TO USE INHERITANCE?

 If we create a class Vehicle and write these three functions in it and inherit the rest of the classes
from the vehicle class, then we can simply avoid the duplication of data and increase re-usabilit
7
IMPLEMENTING INHERITANCE IN C++

 For creating a sub-class which is inherited from the base class we have to
follow the below syntax.
 Syntax:
class subclass_name : access_mode base_class_name
{
//body of subclass
};
 Here, subclass_name is the name of the sub class, access_mode is the mode
in which you want to inherit this sub class for example: public, private etc.
and base_class_name is the name of the base class from which you want to
inherit the sub class.
 // Base class int main() {
 class Vehicle { Car myCar;
 public: myCar.honk();
 string brand = "Ford";
cout << myCar.brand + " " + myCar.model;

return 0;
void honk() {
}
 cout << "Tuut, tuut! \n" ;
 }
 };
 // Derived class
 class Car: public Vehicle {
 public:
 string model = "Mustang";
 };
Inheritance

 Inheritance allows a derived class to inherit properties and behaviors


(methods) from a base class.

 Enables the creation of a new class based on an existing class,


promoting code reuse and the extension of existing functionality.

 Supports polymorphism, where a base class reference can point to


objects of derived classes.
11
PUBLIC, PRIVATE AND PROTECTED INHERITANCE

1. Public Inheritance
Consider the dummy code given below for inheritance.
class B : public A
{
}:
The line class B : public A tells the compiler that we are inheriting class A in class B in public followings
:
(a) All the public members of class A becomes public members of class B.
(b) All the protected members of class A becomes protected members of class B.
(c) Private members are never inherited.
12
2. PRIVATE INHERITANCE

Consider the dummy code given below for inheritance:


class B : private A
{
}:
The line class B : private A tells the compiler that we are inheriting class A in class B in
private mode. In private mode inheritance note the following points:
(a) All the public members of class A becomes private members of the class B.
(b) All the protected members of the class A becomes private members of class B.
(c) Private members are never inherited.
13

The above dummy code can be written as too.


class B : A
{
}:

As the default inheritance mode is private mode.


14
PROTECTED INHERITANCE

Consider the dummy code given below for inheritance:


class B : protected A
{
}:
The line class B : protected A tells the compiler that we are inheriting class A in class B in
protected mode. In protected mode inheritance note the following points:
(a) All the public members of class A becomes protected members of class B.
(b) All the protected members of class A becomes protected members of class B.
(c) Private members are never inherited.
Protected Members

 Protected members of a class are accessible within the class itself and by derived classes.

 They provide a level of encapsulation that allows derived classes to access and modify
these members while keeping them hidden from other parts of the program.

 Useful for creating a controlled interface for derived classes.


class Base {
protected:
int protectedVar;
public:
Base() : protectedVar(0) {}
};

class Derived : public Base {


public:
void setProtectedVar(int val) {
protectedVar = val;
}
};
Protected Base Class Inheritance

 When a class is inherited as protected, the public and protected members of the base class
become protected members of the derived class.

 This restricts access to these members outside the inheritance hierarchy, providing an
additional layer of encapsulation.

 Useful in scenarios where the derived class should not expose the base class's public
interface.
class Base {
public:
void display() {
std::cout << "Base class display function." <<
std::endl;
}
};

class Derived : protected Base {


public:
void show() {
display(); // Accessing protected base class method
}
};
Types of inheritance

• Single Inheritance
Single Inheritance is the most primitive among all the types of inheritance in C++. In this
inheritance, a single class inherits the properties of a base class. All the data members of
the base class are accessed by the derived class according to the visibility mode (i.e.,
private, protected, and public) that is specified during the inheritance.
 Syntax
class base_class_1
{
// class definition
};
class derived_class: visibility_mode base_class_1
{
// class definition
};
Example
#include <iostream>
using namespace std; int main(void) {
Dog d1;
class Animal {
d1.eat();
public: d1.bark();
void eat() { return 0;
cout<<"Eating..."<<endl; }
}
};
class Dog: public Animal
{
public:
void bark(){
cout<<"Barking...";
}
• Multilevel Inheritance
 The inheritance in which a class can be derived from another derived class is known as
Multilevel Inheritance. Suppose there are three classes A, B, and C. A is the base class that
derives from class B. So, B is the derived class of A. Now, C is the class that is derived from
class B. This makes class B, the base class for class C but is the derived class of class A. This
scenario is known as the Multilevel Inheritance. The data members of each respective base
class are accessed by their respective derived classes according to the specified visibility
modes.
 Syntax
class class_A
{
// class definition
};
class class_B: visibility_mode class_A
{
// class definition
};
class class_C: visibility_mode class_B
{
// class definition
};
#include <iostream>
using namespace std; class BabyDog: public Dog
{
class Animal {
public:
public: void weep() {
void eat() { cout<<"Weeping...";
}
cout<<"Eating..."<<endl;
};
} int main(void) {
}; BabyDog d1;
d1.eat();
class Dog: public Animal d1.bark();
{ d1.weep();
public:
return 0;
}
void bark(){
cout<<"Barking..."<<endl;
}
• Multiple Inheritance
 The inheritance in which a class can inherit or derive the characteristics of multiple
classes, or a derived class can have over one base class, is known as Multiple
Inheritance. It specifies access specifiers separately for all the base classes at the time
of inheritance. The derived class can derive the joint features of all these classes and
the data members of all the base classes are accessed by the derived or child class
according to the access specifiers.
 Syntax
 class base_class_1
 {
 // class definition
 };
 class base_class_2
 {
 // class definition
 };
 class derived_class: visibility_mode_1 base_class_1, visibility_mode_2 base_class_2
 {
 // class definition
 };
class C : public A,public B
#include <iostream> class B {
using namespace std; { public:
void display()
class A protected: {
{
int b; std::cout << "The value of a is : " <<a<< std::endl;
public: std::cout << "The value of b is : " <<b<< std::endl;
protected: cout<<"Addition of a and b is : "<<a+b;
void get_b(int n)
int a; }
{ };
public: b = n; int main()
void get_a(int n) } {
C c;
{ }; c.get_a(10);
a = n; c.get_b(20);
c.display();
}
}; return 0;
}
 Hierarchical Inheritance
 The inheritance in which a single base class inherits multiple derived classes is known
as the Hierarchical Inheritance. This inheritance has a tree-like structure since every
class acts as a base class for one or more child classes. The visibility mode for each
derived class is specified separately during the inheritance and it accesses the data
members accordingly
Syntax

Class A
{
............
};
Class B: access_specifier A
{
.........
};
Class C: access_specifier A
{
.............
};
class C : public A //subclass C
{
#include<iostream> public:
using namespace std; void show_C() {
cout<<"class C"<<endl;
class A //superclass A }
};
{
public: int main() {
void show_A() { B b; // b is object of class B
cout<<"class A"<<endl; cout<<"calling from B: "<<endl;
} b.show_B();
}; b.show_A();
class B : public A //subclass B
{ C c; // c is object of class C
cout<<"calling from C: "<<endl;
public:
c.show_C();
void show_B() { c.show_A();
cout<<"class B"<<endl; return 0;
} }
};
 Hybrid Inheritance
 Hybrid inheritance is a combination of more than one type of inheritance.
Syntax
class class_A
class class_D: visibility_mode class_C
{ {
// class definition // class definition
};
};
class class_E: visibility_mode class_C
class class_B {
{ // class definition
};
// class definition
};
class class_C: visibility_mode class_A, visibility_mode class_B
{
// class definition
};
Diamond Problem

 The diamond problem in inheritance happens when there is a derived


class inheriting the attributes of 2 superclasses, and these superclasses
have a common base class. The following diagram represents the
structure of a diamond problem.
 In a diamond problem, when the two classes class_1 and class_2 inherit the same base
class, it creates two copies of the Base_class. So when an object of the derived_class
accesses a member of the base class, it causes ambiguity. This ambiguous situation is
caused because it is unclear which copy of the base_class member needs to be accessed.
And in such a situation the compiler throws an error.
#include <iostream> // class 2 int main()
using namespace std; class class_2 : public {
// base class Base_class // create an object of the
{ derived_class
class Base_class
public: derived_class obj;
{ int z; obj.x = 10; // ambiguous
public: }; obj.y = 20;
int x; // derived class 3 obj.z = 30;
}; class derived_class : public obj.sum = obj.x + obj.y +
class_1, public class_2 obj.z;
// class 1
{ cout << "The sum is: " <<
class class_1 : public Base_class public: obj.sum << "\n\n";
{ int sum; return 0;
public: }; }
int y;
};
 There are two ways to avoid the ambiguous situation in a diamond
problem.
1. Using the scope resolution operator.
2. Using virtual base class keyword.
1. 2.
int main() class class_1 : virtual public Base_class
{ {
public:
// create an object of the derived_class
int y;
derived_class obj; };
obj.class_1::x = 10; // it is now unambiguous
obj.y = 20;
obj.z = 30;
obj.sum = obj.class_1::x + obj.y + obj.z;
cout << "The sum is: " << obj.sum << "\n\n";
return 0;
}
Inheriting Multiple Base Classes

 A derived class can inherit from multiple base classes, combining their functionalities.

 This allows the creation of complex classes that integrate features from several sources.

 Requires careful management to avoid ambiguities, especially when base classes have
members with the same names.
class Base1 {
public:
void display() {
std::cout << "Base1 display function." << std::endl;
}
};

class Base2 {
public:
void show() {
std::cout << "Base2 show function." << std::endl;
}
};

class Derived : public Base1, public Base2 {


public:
void print() {
display();
show();
}
};
Constructors, Destructors, and
Inheritance

 Constructors and destructors in derived classes manage initialization and cleanup,


leveraging base class constructors and destructors.

 Base class constructors are called before derived class constructors, ensuring proper
initialization.

 Destructors are called in the reverse order, with derived class destructors executing before
base class destructors.
class Base {
public:
Base() {
std::cout << "Base class constructor." << std::endl;
}
~Base() {
std::cout << "Base class destructor." << std::endl;
}
};

class Derived : public Base {


public:
Derived() {
std::cout << "Derived class constructor." << std::endl;
}
~Derived() {
std::cout << "Derived class destructor." << std::endl;
}
};
Passing Parameters to Base Class
Constructors

 Derived class constructors can pass arguments to base class constructors to initialize base
class members.

 This allows for flexible and dynamic initialization of inherited attributes.

 Ensures that the base class is properly set up before the derived class adds its own
initialization logic.
class derived: public base { int main()
#include <iostream>
int j; {
using namespace std; public: derived ob(3, 4);
// derived uses x; y is passed along to base.
ob.show(); // displays 4 3
class base { derived(int x, int y): base(y)
protected: { return 0;
j = x; cout << "Constructing derived\n"; }
int i; }
public:
~derived()
base(int x) { { cout << "Destructing derived\n"; }
i = x; cout << "Constructing base\n"; }
void show() { cout << i << " " << j << "\
~base() { cout << "Destructing base\
n"; }
n"; }
};
};
Multiple class base2 {
protected:
int k;
public: int main()
#include <iostream> {
using namespace std; base2(int x) {
k = x; cout << "Constructing base2\n"; } derived ob(3, 4,
5);
class base1
protected: ~base2() { cout << "Destructing base2\n"; }
}; ob.show(); //
int i; displays 4 3 5
public:
base1(int x) { class derived: public base1, public base2 {
int j; return 0;
i = x; cout << "Constructing base1\n"; }
} public:
~base1() { cout << "Destructing base1\ derived(int x, int y, int z): base1(y), base2(z)
n"; } {
}; j = x; cout << "Constructing derived\n"; }

~derived() {
cout << "Destructing derived\n"; }
void show() { cout << i << " " << j << " " <<
k << "\n"; }};
class Base {
protected:
int baseVar;
public:
Base(int val) : baseVar(val) {
std::cout << "Base class constructor with value: " <<
baseVar << std::endl;
}
};

class Derived : public Base {


public:
Derived(int val) : Base(val) {
std::cout << "Derived class constructor with value: " <<
baseVar << std::endl;
}
};
Granting Access

 Friend functions and friend classes can access the private and protected members of a
class.

 This is useful for functions and classes that require intimate knowledge of another class’s
implementation details.

 Provides a controlled way to expose class internals for specific purposes without breaking
encapsulation.
class Base {
friend class FriendClass;
private:
int secret;
public:
Base() : secret(42) {}
};

class FriendClass {
public:
void revealSecret(Base& b) {
std::cout << "Secret value is: " << b.secret <<
std::endl;
}
};
Virtual Base Classes

 Virtual base classes are used to prevent multiple "instances" of a base class when using
multiple inheritance.

 They ensure that the base class is only inherited once, regardless of how many times it
appears in the inheritance hierarchy.

 Solves the "diamond problem" in multiple inheritance.


class Base {
public:
void display() {
std::cout << "Base class display function." <<
std::endl;
}
};

class Derived1 : virtual public Base {};


class Derived2 : virtual public Base {};

class FinalDerived : public Derived1, public Derived2


{};
File
Practical
 #include <iostream>
 using namespace std;
 class Point { int main()

 private: {

 Point t1(10, 15);


int x;
 cout << "x = " << t1.getX() << ", ";
int y;
cout << "y = " << t1.getY();
 public:
return 0;
 Point(int i = 0, int j = 0): x(i), y(j) {}
}
 int getX() const { return x; }
 int getY() const { return y; }
 };
// Method to display employee details


void displayDetails() const {
#include <iostream>
 #include <string> cout << "Name: " << name << ", Age: " << age << ", Salary: " <<
salary << endl;
 using namespace std;
}
 class Employee {
 };
private:
 string name; int main() {
 int age; // Creating objects of Employee using initializer list
 double salary; Employee emp1("Rohit", 30, 50000);
 public: emp1.displayDetails();
 // Parameterized constructor using initializer list
Employee emp2("Ravi", 28, 60000);
 Employee(const string& n, int a, double s)
emp2.displayDetails();
 : name(n), age(a), salary(s) {

return 0;
// Constructor body
 } }
class Box {

private:
Write a program to demonstrate the overloading of memory management operators.
int length;

int width;

int height;
// Overloading delete operator for memory
int* data; deallocation int main() {

public: void operator delete(void* p) { // Using overloaded new operator for


dynamic allocation
Box(int l, int w, int h) : length(l), width(w), cout << "Overloaded delete operator called\
height(h), data(nullptr) { n"; Box* box = new Box(10, 20, 30);

cout << "Constructor called\n"; ::delete p; // Deallocate memory using box->display();


global delete operator
} // Using overloaded delete operator to
} deallocate memory
void* operator new(size_t size) {
// Method to display box dimensions delete box;
cout << "Overloaded new operator called, size: "
<< size << endl; void display() const { return 0;

void* p = ::new Box(0, 0, 0); // Allocate memory cout << "Dimensions: " << length << " x " }
using global new operator << width << " x " << height << endl;
return p; }
} };

You might also like