Oops Concepts
Oops Concepts
1.Encapsulation
2.Abstraction
3.Inheritance
4.Polymorphism
1. Encapsulation
Example:
#include <iostream>
using namespace std;
class Student {
private:
int age; // Private data member
string name;
public:
void setData(string studentName, int studentAge) {
name = studentName;
age = studentAge;
}
void getData() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
int main() {
Student s;
s.setData("Shankar", 22);
s.getData();
return 0;
}
Key Points:
age and name are private, meaning they cannot be accessed directly outside the
class.
Data is modified only through setData() and accessed via getData(), ensuring
controlled access.
Example:
#include <iostream>
using namespace std;
class Car {
public:
void start() {
cout << "Car is starting..." << endl;
engine(); // Internal function not exposed to the user
}
private:
void engine() {
cout << "Engine is running..." << endl;
}
};
int main() {
Car myCar;
myCar.start(); // User only sees "Car is starting..."
// myCar.engine(); // ERROR: Private method cannot be accessed
return 0;
}
Key Points:
An abstract class in C++ is a class that contains at least one pure virtual
function. A pure virtual function is a function that has no implementation in the
base class and must be overridden in derived classes. Abstract classes cannot be
instantiated, meaning you cannot create objects of an abstract class.
#include <iostream>
using namespace std;
// Abstract class
class Shape {
public:
// Pure virtual function (no implementation in the base class)
virtual void draw() = 0;
void commonFunction() {
cout << "This is a common function in all shapes.\n";
}
};
int main() {
// Shape s; // Error: Cannot instantiate an abstract class
delete s1;
delete s2;
return 0;
}
Explanation
The Shape class is an abstract class because it has a pure virtual function
(draw()).
The Circle and Rectangle classes inherit from Shape and provide their own
implementation of draw().
We cannot create an object of Shape directly.
However, we can use pointers of type Shape* to refer to objects of derived classes.
Output:
Drawing a Circle.
This is a common function in all shapes.
Drawing a Rectangle.
An interface is a special type of abstract class where all functions are pure
virtual and it does not contain any data members.
#include <iostream>
using namespace std;
int main() {
Animal* a1 = new Dog();
a1->makeSound();
a1->move();
Animal* a2 = new Bird();
a2->makeSound();
a2->move();
delete a1;
delete a2;
return 0;
}
Explanation
The Animal class is an interface because it has only pure virtual functions.
Any class that inherits from Animal must implement all functions.
Interfaces allow multiple inheritance in C++.
Output:
Dog barks.
Dog runs.
Bird chirps.
Bird flies.
#include <iostream>
using namespace std;
class Car {
private:
int speed; // Hidden data (implementation detail)
public:
void setSpeed(int s) {
if (s > 0) {
speed = s;
} else {
cout << "Speed must be positive.\n";
}
}
int getSpeed() {
return speed;
}
};
int main() {
Car myCar;
myCar.setSpeed(50);
cout << "Car speed: " << myCar.getSpeed() << " km/h\n";
return 0;
}
Explanation
The speed variable is private, so it cannot be accessed directly from outside the
class.
Instead, we use public functions (setSpeed() and getSpeed()) to control access.
This ensures that only valid values can be assigned to speed.
Output
Car speed: 50 km/h
Inheritance in oops(C++)
Syntax of Inheritance
class Base {
// Base class members
};
1.Single Inheritance
Example:
#include <iostream>
using namespace std;
class Base {
public:
void show() {
cout << "Base class method" << endl;
}
};
int main() {
Derived obj;
obj.show(); // Accessing base class method
return 0;
}
Output:
Base class method
2. Multiple Inheritance
Example:
class A {
public:
void showA() { cout << "Class A" << endl; }
};
class B {
public:
void showB() { cout << "Class B" << endl; }
};
int main() {
C obj;
obj.showA();
obj.showB();
return 0;
}
3.Multilevel Inheritance
Example:
class A {
public:
void showA() { cout << "Class A" << endl; }
};
class B : public A {
public:
void showB() { cout << "Class B" << endl; }
};
class C : public B {
public:
void showC() { cout << "Class C" << endl; }
};
int main() {
C obj;
obj.showA();
obj.showB();
obj.showC();
return 0;
}
4.Hierarchical Inheritance
Example:
class A {
public:
void showA() { cout << "Class A" << endl; }
};
class B : public A {
public:
void showB() { cout << "Class B" << endl; }
};
class C : public A {
public:
void showC() { cout << "Class C" << endl; }
};
int main() {
B obj1;
C obj2;
obj1.showA();
obj2.showA();
return 0;
}
Access specifiers control how members of the base class are inherited in the
derived class.
class Base {
public:
int a = 10;
protected:
int b = 20;
private:
int c = 30;
};
class Derived : public Base {
public:
void display() {
cout << "a: " << a << endl; // Accessible (public in base → public in
derived)
cout << "b: " << b << endl; // Accessible (protected in base → protected in
derived)
// cout << "c: " << c; // Not accessible (private members are not
inherited)
}
};
----------------------------------------
Constructor & Destructor in Inheritance
-----------------------------------------
> Base class constructor is executed first, followed by the derived class
constructor.
> Destructors are called in reverse order (derived class first, then base class).
Example:
class Base {
public:
Base() { cout << "Base Constructor\n"; }
~Base() { cout << "Base Destructor\n"; }
};
int main() {
Derived obj;
return 0;
}
Output:
Base Constructor
Derived Constructor
Derived Destructor
Base Destructor
The diamond problem occurs in multiple inheritance when a derived class inherits
from two base classes that have a common ancestor.
class A {
public:
void show() { cout << "A's show()" << endl; }
};
int main() {
D obj;
obj.show(); // No ambiguity due to virtual inheritance
return 0;
}
----------------------------
Polymorphism in OOPs (C++)
----------------------------
1. Compile-time Polymorphism
Function Overloading
-----------------------
Function overloading allows multiple functions with the same name but different
parameters.
#include <iostream>
using namespace std;
class Math {
public:
int add(int a, int b) {
return a + b;
}
int main() {
Math obj;
cout << "Sum (int): " << obj.add(5, 10) << endl;
cout << "Sum (double): " << obj.add(5.5, 10.5) << endl;
return 0;
}
Operator Overloading
-----------------------
#include <iostream>
using namespace std;
class Complex {
public:
int real, imag;
// Overloading + operator
Complex operator+(const Complex& obj) {
return Complex(real + obj.real, imag + obj.imag);
}
void display() {
cout << real << " + " << imag << "i" << endl;
}
};
int main() {
Complex c1(3, 2), c2(1, 7);
Complex c3 = c1 + c2; // Calls overloaded + operator
c3.display();
return 0;
}
2. Run-time Polymorphism
--------------------------
When a derived class redefines a function of the base class, and the function is
marked as virtual, runtime polymorphism is achieved.
#include <iostream>
using namespace std;
class Base {
public:
virtual void show() { // Virtual function
cout << "Base class function" << endl;
}
};
int main() {
Base* basePtr;
Derived obj;
basePtr = &obj;
___________________________________________________________________________________
___________
Class: A blueprint for creating objects. It defines properties (data members) and
behaviors (member functions).
Object: An instance of a class.
Example:
#include <iostream>
using namespace std;
class Car {
public:
string brand;
int speed;
void showDetails() {
cout << "Brand: " << brand << ", Speed: " << speed << " km/h" << endl;
}
};
int main() {
Car car1; // Object creation
car1.brand = "Toyota";
car1.speed = 120;
car1.showDetails();
return 0;
}
___________________________________________________________________________________
_____________
The function that will be called is determined before the program runs.
class A {
public:
void show() { // No virtual keyword
cout << "Static Binding: Class A" << endl;
}
};
int main() {
A obj;
obj.show(); // Static binding occurs here
return 0;
}
🔹 Why Static Binding?
Since show() is a normal member function (not virtual), the compiler directly
resolves the function call at compile time.
The function that will be called is determined while the program is running.
Slightly slower due to runtime function resolution via vtable (Virtual Table) and
vptr (Virtual Pointer).
class Base {
public:
virtual void show() { // Virtual function
cout << "Dynamic Binding: Base Class" << endl;
}
};
int main() {
Base* bptr; // Pointer of base class
Derived d;
bptr = &d;