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

Oops Concepts

The document provides an overview of the four pillars of Object-Oriented Programming (OOP): Encapsulation, Abstraction, Inheritance, and Polymorphism, with detailed explanations and C++ code examples for each concept. It covers key aspects such as access modifiers, types of inheritance, and the distinction between compile-time and run-time polymorphism. Additionally, it discusses constructors, destructors, and binding in OOP, emphasizing their importance in C++ programming.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

Oops Concepts

The document provides an overview of the four pillars of Object-Oriented Programming (OOP): Encapsulation, Abstraction, Inheritance, and Polymorphism, with detailed explanations and C++ code examples for each concept. It covers key aspects such as access modifiers, types of inheritance, and the distinction between compile-time and run-time polymorphism. Additionally, it discusses constructors, destructors, and binding in OOP, emphasizing their importance in C++ programming.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 14

############## OOPS Interview Preparations ###############

The four pillars of Object-Oriented Programming (OOP) are:

1.Encapsulation
2.Abstraction
3.Inheritance
4.Polymorphism

1. Encapsulation

Encapsulation is the concept of wrapping data (variables) and methods (functions)


into a single unit (class). It helps in data hiding, meaning that the internal
representation of an object is hidden from the outside world.

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.

Access Modifiers: C++ provides three access specifiers to enforce encapsulation:

private: Members are accessible only within the same class.


protected: Members are accessible within the same class and derived classes.
public: Members are accessible from outside the class.
Real-Life Example of Encapsulation: ATM Machine
An ATM machine follows the principle of encapsulation by hiding internal account
details and allowing access only through specific functions:

Private Data: Account balance is not directly accessible to users.


Public Methods: Users can only interact via predefined functions like:
Withdraw Money
Deposit Money
Check Balance
Controlled Access: Users cannot modify the bank’s internal data directly, ensuring
security and data protection.

Abstraction in OOPs (C++)

Abstraction is one of the fundamental principles of Object-Oriented Programming


(OOPs). It is the process of hiding the implementation details from the user and
only exposing the necessary functionalities.

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:

engine() is private and hidden from the user.


The user can only call start(), which internally calls engine().
This hides unnecessary implementation details and provides a simple interface.

In C++, abstraction is achieved using:


1.Abstract classes (with pure virtual functions)
2.Interfaces (only pure virtual functions)
3.Access specifiers (private, protected, public)

1. Abstract Classes (with Pure Virtual Functions)

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.

Example: Abstract Class in C++

#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";
}
};

// Derived class implementing the pure virtual function


class Circle : public Shape {
public:
void draw() override {
cout << "Drawing a Circle.\n";
}
};

// Another derived class


class Rectangle : public Shape {
public:
void draw() override {
cout << "Drawing a Rectangle.\n";
}
};

int main() {
// Shape s; // Error: Cannot instantiate an abstract class

Shape* s1 = new Circle();


s1->draw();
s1->commonFunction();

Shape* s2 = new Rectangle();


s2->draw();

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.

2. Interfaces (Only Pure Virtual Functions)

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;

// Interface (Only pure virtual functions)


class Animal {
public:
virtual void makeSound() = 0; // Pure virtual function
virtual void move() = 0; // Another pure virtual function
};

// Derived class implementing all pure virtual functions


class Dog : public Animal {
public:
void makeSound() override {
cout << "Dog barks.\n";
}

void move() override {


cout << "Dog runs.\n";
}
};

// Another derived class


class Bird : public Animal {
public:
void makeSound() override {
cout << "Bird chirps.\n";
}

void move() override {


cout << "Bird flies.\n";
}
};

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.

3. Access Specifiers (private, protected, public)


Access specifiers in C++ control how class members (variables and functions) can be
accessed. They help achieve abstraction by hiding implementation details.

Example: Using Access Specifiers for Abstraction

#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++)

Inheritance is one of the key features of Object-Oriented Programming (OOP) in C++.


It allows one class (called the derived class) to inherit the properties and
behavior of another class (called the base class). This promotes code reusability,
modularity, and hierarchy representation.

Syntax of Inheritance

class Base {
// Base class members
};

class Derived : public Base { // 'public' denotes mode of inheritance


// Derived class members
};

Types of Inheritance in C++

1.Single Inheritance

A single derived class inherits from a single base class.

Example:

#include <iostream>
using namespace std;

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

class Derived : public Base {


};

int main() {
Derived obj;
obj.show(); // Accessing base class method
return 0;
}

Output:
Base class method

2. Multiple Inheritance

A derived class inherits from more than one base class.

Example:

class A {
public:
void showA() { cout << "Class A" << endl; }
};

class B {
public:
void showB() { cout << "Class B" << endl; }
};

class C : public A, public B {


};

int main() {
C obj;
obj.showA();
obj.showB();
return 0;
}

3.Multilevel Inheritance

A class is derived from another derived class.

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

Multiple classes inherit from a single base class.

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;
}

5. Hybrid (Multiple + Multilevel) Inheritance

Combination of multiple and multilevel inheritance

Access Specifiers in Inheritance

Access specifiers control how members of the base class are inherited in the
derived class.

Base Class Members public Inheritance protected Inheritance private


Inheritance
public members public protected private
protected members protected protected private
private members Not Inherited Not Inherited Not
Inherited

Example of Access Specifiers in Inheritance

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"; }
};

class Derived : public Base {


public:
Derived() { cout << "Derived Constructor\n"; }
~Derived() { cout << "Derived Destructor\n"; }
};

int main() {
Derived obj;
return 0;
}

Output:
Base Constructor
Derived Constructor
Derived Destructor
Base Destructor

Virtual Base Class (To Avoid Diamond Problem)

The diamond problem occurs in multiple inheritance when a derived class inherits
from two base classes that have a common ancestor.

Solution: Use virtual keyword while inheriting.

class A {
public:
void show() { cout << "A's show()" << endl; }
};

class B : virtual public A {}; // Virtual Inheritance


class C : virtual public A {}; // Virtual Inheritance

class D : public B, public C {};

int main() {
D obj;
obj.show(); // No ambiguity due to virtual inheritance
return 0;
}

----------------------------
Polymorphism in OOPs (C++)
----------------------------

Polymorphism is one of the four main pillars of Object-Oriented Programming (OOP)


(along with Encapsulation, Inheritance, and Abstraction). It allows a function or
an object to behave differently based on the context.

Types of Polymorphism in C++


-------------------------------
Polymorphism in C++ can be categorized into two types:

1.Compile-time Polymorphism (Static Binding)

Achieved using Function Overloading and Operator Overloading.


The function to be executed is determined at compile-time.

2.Run-time Polymorphism (Dynamic Binding)

Achieved using Function Overriding and Virtual Functions.


The function call is resolved at runtime using pointers and dynamic dispatch.

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;
}

double add(double a, double b) { // Overloaded function


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
-----------------------

Allows overloading operators for user-defined types.

#include <iostream>
using namespace std;

class Complex {
public:
int real, imag;

Complex(int r, int i) : real(r), imag(i) {}

// 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
--------------------------

Function Overriding (Virtual Functions)

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;
}
};

class Derived : public Base {


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

int main() {
Base* basePtr;
Derived obj;
basePtr = &obj;

basePtr->show(); // Calls Derived class function (runtime polymorphism)


return 0;
}

___________________________________________________________________________________
___________

Class and Object

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;
}

___________________________________________________________________________________
_____________

In C++ Object-Oriented Programming (OOP), binding refers to the process of linking


a function call to its corresponding function definition. There are two types of
binding:

1. Static Binding (Early Binding)


Happens at compile time.

The function that will be called is determined before the program runs.

Used in function overloading and operator overloading.

Achieved using normal function calls (without virtual keyword).

Faster execution since function calls are resolved at compile time.

Example of Static Binding:


cpp
Copy
Edit
#include <iostream>
using namespace std;

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.

2. Dynamic Binding (Late Binding)


Happens at runtime.

The function that will be called is determined while the program is running.

Used in method overriding (when a derived class provides a different implementation


for a function defined in a base class).

Achieved using virtual functions.

Slightly slower due to runtime function resolution via vtable (Virtual Table) and
vptr (Virtual Pointer).

Example of Dynamic Binding:


cpp
Copy
Edit
#include <iostream>
using namespace std;

class Base {
public:
virtual void show() { // Virtual function
cout << "Dynamic Binding: Base Class" << endl;
}
};

class Derived : public Base {


public:
void show() override { // Overriding the base class function
cout << "Dynamic Binding: Derived Class" << endl;
}
};

int main() {
Base* bptr; // Pointer of base class
Derived d;
bptr = &d;

bptr->show(); // Dynamic binding occurs here


return 0;
}
🔹 Why Dynamic Binding?
Since show() is marked as virtual in the base class, the function call is resolved
at runtime using the vtable mechanism, allowing the correct function from the
derived class to be invoked.

You might also like