0% found this document useful (0 votes)
7 views

lect07&08_unit03_Polymorphism (1)

Uploaded by

fosefan745
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

lect07&08_unit03_Polymorphism (1)

Uploaded by

fosefan745
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

Paper Code: CIC-211

Subject: Object-Oriented Programming Using C++

Unit03, Lecture 07 & 08:

Topics Covered: Polymorphism, categorization of polymorphic techniques,


polymorphism by parameter, parametric polymorphism, generic function –
template function, function overriding, run time polymorphism, virtual functions.
Pure Virtual Function and Abstract Class

Polymorphism:

Polymorphism is a core concept in Object-Oriented Programming (OOP) that allows methods,


operators, or objects to behave differently based on their context. In C++, polymorphism allows
objects of different classes to be treated as objects of a common base class. It can be classified
into two major types:

 Compile-time Polymorphism (also known as Static Polymorphism)


 Run-time Polymorphism (also known as Dynamic Polymorphism)

Categorization of Polymorphic Techniques

1. Compile-time Polymorphism: This occurs during the compilation of the program.


Examples include:
o Function overloading
o Operator overloading
o Templates
2. Run-time Polymorphism: This happens during the execution of the program and
typically involves:
o Function overriding (using inheritance)
o Virtual functions

1. Compile-time Polymorphism: Polymorphism by Parameter

This refers to polymorphism achieved by passing parameters of different types to functions or


methods.

a. Function Overloading

Function overloading allows multiple functions to have the same name but different parameter
lists. The compiler decides which function to invoke based on the arguments passed.

Syntax:
class MathOperation {
public:
int add(int a, int b) {
return a + b;
}

float add(float a, float b) {


return a + b;
}
};

Example-

#include <iostream>
using namespace std;

class MathOperation {
public:
int add(int a, int b) {
return a + b;
}

float add(float a, float b) {


return a + b;
}
};

int main() {
MathOperation obj;
cout << "Integer addition: " << obj.add(5, 10) << endl; // Calls int add(int, int)
cout << "Float addition: " << obj.add(5.5f, 10.5f) << endl; // Calls float add(float,
float)

return 0;
}

Output:

Integer addition: 15

Float addition: 16
b. Templates

i. Template Functions (Generic Functions)

A template function is a single function that works with any data type. The function definition
uses a template keyword followed by a type parameter.

Syntax:

template <typename T>


T add(T a, T b) {
return a + b;
}

Example –

#include <iostream>
using namespace std;

template <typename T>


T add(T a, T b) {
return a + b;
}

int main() {
cout << "Integer addition: " << add(5, 10) << endl; // Calls add<int>(int, int)
cout << "Float addition: " << add(5.5, 10.5) << endl; // Calls add<float>(float,
float)

return 0;
}

Output:

Integer addition: 15

Float addition: 16
ii. Template Classes

Templates can also be applied to classes to create generic classes. These classes can work
with any data type.

Example:

#include <iostream>
using namespace std;

template <typename T>


class Calculator {
public:
T add(T a, T b) {
return a + b;
}

T subtract(T a, T b) {
return a - b;
}
};

int main() {
Calculator<int> intCalc;
Calculator<float> floatCalc;

cout << "Integer addition: " << intCalc.add(10, 20) << endl;
cout << "Float addition: " << floatCalc.add(5.5, 10.5) << endl;
cout << "Float Subtraction: " << floatCalc.subtract(5.5, 10.5) << endl;
return 0;
}

Output:

Integer addition: 30

Float addition: 16

Float Subtraction: -5
2. Run-time Polymorphism

Run-time polymorphism is achieved through inheritance and virtual functions. In this


case, the function to be invoked is determined at runtime based on the type of the object
being pointed to by a pointer/reference.

Function Overriding

Function overriding occurs when a derived class defines a function that is already
defined in its base class, but with different behavior. It is an example of run-time
polymorphism.

Syntax:

class Base {
public:
virtual void show() {
cout << "Base class show function" << endl;
}
};

class Derived : public Base {


public:
void show() override { // Function overriding
cout << "Derived class show function" << endl;
}
};
Example1:

#include <iostream>
using namespace std;

class Base {
public:
virtual void show() {
cout << "Base class show function" << endl;
}
};

class Derived : public Base {


public:
void show() override {
cout << "Derived class show function" << endl;
}
};

int main() {
Base *basePtr;
Derived derivedObj;

basePtr = &derivedObj;
basePtr->show(); // Calls Derived's show()

return 0;
}
Explanation:

 The base class method show() is declared as virtual, allowing the derived class to override
it.
 The override keyword is optional but recommended as it signals the compiler that the
method is intended to override a base class method.
Example 2:

#include <iostream>
using namespace std;

class Animal {
public:
virtual void sound() {
cout << "Animal makes sound" << endl;
}
};

class Dog : public Animal {


public:
void sound() override {
cout << "Dog barks" << endl;
}
};

class Cat : public Animal {


public:
void sound() override {
cout << "Cat meows" << endl;
}
};

int main() {
Animal *animalPtr;
Dog dogObj;
Cat catObj;

// Pointer to Dog object


animalPtr = &dogObj;
animalPtr->sound(); // Calls Dog's sound()

// Pointer to Cat object


animalPtr = &catObj;
animalPtr->sound(); // Calls Cat's sound()

return 0;
}
Explanation:

 The sound() function in the Animal class is declared as virtual, which allows the
function to be overridden in the derived classes (Dog and Cat).
 The decision of which sound() function to call is made at runtime depending on the
actual type of object being pointed to by animalPtr.

Key Differences:
Feature Compile-time Polymorphism Run-time Polymorphism
Binding time Compile-time Run-time
Function overloading, Operator Function overriding, Virtual
Techniques used
overloading, Templates functions
Faster as resolved during compile
Performance Slower due to runtime resolution
time
Flexibility Less flexible More flexible

Pure Virtual Functions & Abstract Class-


A pure virtual function is a function declared in a base class that has no implementation in that
class. It is meant to be overridden by derived classes. The primary purpose of pure virtual functions
is to define a common interface for all the derived classes, forcing them to provide their specific
implementations of the function.

In C++, pure virtual functions are declared by assigning the value 0 in the base class declaration,
like this:

class Base {
public:
virtual void myFunction() = 0; // Pure virtual function
};
Key Characteristics of a Pure Virtual Function:

1. No Implementation in Base Class: The base class does not provide the implementation
for the pure virtual function, leaving it up to the derived classes.
2. Abstract Base Class: A class containing at least one pure virtual function becomes an
abstract class. This means you cannot create objects of this class directly.
3. Must be Overridden: All derived classes are required to provide their own
implementation of the pure virtual function, or they themselves will also be abstract classes.
4. Used for Polymorphism: Pure virtual functions enable polymorphism, allowing the base
class to define a general interface that all derived classes must implement.

Example-

#include <iostream>

// Abstract class with a pure virtual function


class Shape {
public:
virtual void draw() = 0; // Pure virtual function
};

class Circle : public Shape {


public:
void draw() override {
std::cout << "I am Drawing Circle" << std::endl;
}
};

class Square : public Shape {


public:
void draw() override {
std::cout << " I am Drawing Square" << std::endl;
}
};
int main() {
Shape* shape1 = new Circle();
Shape* shape2 = new Square();

shape1->draw(); // Output: Drawing Circle


shape2->draw(); // Output: Drawing Square

delete shape1;
delete shape2;

return 0;
}

Advantages-
Using pure virtual functions in object-oriented programming offers several benefits, especially
when working with complex systems that rely on polymorphism and abstraction. Here are the key
benefits:

1. Enforcing a Common Interface

Pure virtual functions ensure that all derived classes implement a specific set of functions. This
helps maintain a consistent interface across different subclasses. For example, if you have a base
class Shape with a pure virtual function draw(), every derived class, whether it's Circle, Square,
or Rectangle, must provide an implementation of draw(). This guarantees that all shapes can be
"drawn," even though they might be drawn in different ways.

Benefit: Enforces that all subclasses provide necessary functionality.

2. Supporting Polymorphism

Pure virtual functions enable runtime polymorphism by allowing you to handle objects of
different types through base class pointers or references. For example, you can use a Shape*
pointer to refer to a Circle object or a Square object and call their respective implementations of
the draw() function without knowing their exact type at compile time.

Benefit: Allows for flexible and extensible code that can work with objects of different derived
types through base class pointers.
Shape* shape = new Circle();

shape->draw(); // Calls Circle's draw() method


3. Abstract Base Class (No Object Instantiation)

When you declare a pure virtual function in a class, it makes that class an abstract base class.
This means you cannot instantiate objects of the base class itself, which is useful when you want
to define general behaviors in a base class without allowing the creation of objects of that class.
Only concrete derived classes, which provide implementations for all pure virtual functions, can
be instantiated.

Benefit: Prevents instantiation of incomplete or generalized classes, ensuring only fully


implemented subclasses are used.

4. Decoupling and Code Reusability

By providing an abstract interface through pure virtual functions, you can decouple interface from
implementation. The base class defines the interface, while each derived class provides its own
specific implementation. This makes it easy to reuse the base class and switch out different derived
classes without changing the code that uses them.

Benefit: Increases code reusability and maintainability by decoupling interfaces from


implementations.

5. Extensibility

Pure virtual functions enable extensibility in your software design. You can easily add new
derived classes that implement the pure virtual functions defined in the base class without
modifying existing code. This is particularly important in large-scale applications where new types
might be added frequently.

Benefit: Makes the system easy to extend, allowing for new types without modifying existing
code.

6. Encourages Clear Design and Documentation

The use of pure virtual functions encourages a clear separation of concerns and a well-thought-
out class hierarchy. By requiring derived classes to implement certain functions, the design
becomes more structured, and it is immediately clear what functionality needs to be provided by
any subclass.

Benefit: Promotes a cleaner, well-defined architecture that clearly documents required behaviors
in subclasses.
7. Flexibility and Adaptability

Using pure virtual functions gives developers the flexibility to implement different behaviors in
derived classes while still maintaining a unified interface. This is particularly useful when
developing frameworks or libraries where the exact implementation might be unknown at the time
the base class is designed.

Benefit: Offers flexibility to modify or adapt specific behaviors while maintaining the integrity of
the system interface.

8. Enforcing Design Patterns

Pure virtual functions are commonly used in design patterns such as the Strategy Pattern, Factory
Method Pattern, and Template Method Pattern. These design patterns often rely on pure virtual
functions to define abstract behavior that can be customized by subclasses.

Benefit: Facilitates the use of proven design patterns, leading to better design and code
organization.

References:-
Online

1. Tutorialspoint OOP Tutorial: Comprehensive tutorials on OOP concepts with examples. Link
2. GeeksforGeeks OOP Concepts: Articles and examples on OOP principles and applications. Link
3. https://canvas.rku.ac.in/courses/3333/pages/specifying-a-class

Book(s)

1. "Object-Oriented Analysis and Design with Applications" by Grady Booch: Classic book covering
fundamental OOP concepts and real-world examples.
2. "Object-Oriented Programming in C++" by Robert Lafore: Detailed guide to OOP in C++, explaining
concepts with a practical example

You might also like