💡 Four Pillars of Object-Oriented Programming:
Encapsulation
Inheritance
Abstraction
Polymorphism
// Human class
class Human {
private:
string secret = "humansecret";
public:
int age = 30, weight = 76;
};
// Student class
class Student : private Human {
public:
string name = "student";
void print() {
cout << name << endl;
cout << age << endl;
cout << weight << endl;
}
};
// GStudent class
class GStudent : public Student {
public:
string name = "gstudent";
void print() {
cout << name << endl;
cout << age << endl; // Inaccessible
cout << weight << endl; // Inaccessible
}
};
int main() {
Student s1;
// age, weight became private members of s1.
cout << s1.age << endl; // Inaccessible
cout << s1.weight << endl; // Inaccessible
cout << s1.name << endl; // student
s1.print(); // student 30 76
GStudent g1;
cout << g1.name << endl; // gstudent
cout << g1.age << endl; // Inaccessible
cout << g1.weight << endl; // Inaccessible
return 0;
}
Encapsulation
To encapsulate something
The process of grouping data members and corresponding methods into a single unit is known as Encapsulation.
💡 We can create a fully encapsulated class by making all the data members private.
If the data members are private, they can only be accessed within the class; no other class can access that class’s data members.
Advantages of Encapsulation
Encapsulation is a way to achieve data hiding because other classes will not be able to access the data through the private data members.
It helps hide the data’s internal information, enhancing security.
With encapsulation, you can make the class read-only.
Encapsulation promotes code reusability.
Encapsulated code is better for unit testing.
💡 Encapsulation also makes your code more testable, as you can isolate the unit of functionality that you want to test, and mock or stub the dependencies that you don't.
Summary: Data hiding, Security, Reusability of code, Testing.
Encapsulation in C++ - GeeksforGeeks
Inheritance [Most Important]
In C++, inheritance is a process in which one object automatically acquires all the properties and behaviors
of its parent object. This allows you to reuse, extend, or modify the attributes and behaviors
defined in other classes.
Advantages of Inheritance
The main advantage of inheritance is code
reusability
. We can reuse the code when we inherit the existing class’s methods and fields into a new class.Runtime
polymorphism
(method overriding) can only be achieved through inheritance.
Modes of Inheritance
Public mode: If a subclass is derived from a public base class, the base class’s public members become public in the derived class, and protected members remain protected.
Protected mode: If a subclass is derived from a protected base class, both public and protected members of the base class become protected in the derived class.
Private mode: If a subclass is derived from a private base class, both public and protected members of the base class become private in the derived class. Private members of the parent class are not inherited.
Base class visibility of members ⬇️ | Public | Private | Protected |
Private (no inheritance) | Not Inherited | Not Inherited | Not Inherited |
Protected | Protected | Private | Protected |
Public | Public | Private | Protected |
💡 Private data members of the parent/super class can’t be inherited.
Types of Inheritance
C++ supports five types of inheritance:
Single Inheritance
In single inheritance, one class can extend the functionality of another class. There is only one parent class and one child class.class Animal { public: int age; int weight; void speak() { cout << "Speaking " << endl; } }; class Dog: public Animal { };
Multilevel Inheritance
When a class inherits from a derived class, and the derived class becomes the base class of a new class, it is called multilevel inheritance.class Animal { public: void speak() { cout << "Speaking " << endl; } }; class Dog: public Animal { }; class GermanShepherd: public Dog { };
Multiple Inheritance
In multiple inheritance, a class can inherit more than one class. A single child class can have multiple parent classes.class Animal { public: void bark() { cout << "Barking " << endl; } }; class Human { public: void speak() { cout << "Speaking " << endl; } }; // Multiple Inheritance class HybridClassExample: public Animal, public Human { };
Hierarchical Inheritance
In hierarchical inheritance, one class serves as a base class for more than one derived class.class A { public: void func1() { cout << "Inside Function 1" << endl; } }; class B: public A { public: void func2() { cout << "Inside Function 2" << endl; } }; class C: public A { public: void func3() { cout << "Inside Function 3" << endl; } };
Hybrid Inheritance
Hybrid inheritance is a combination of more than one type of inheritance.
Ambiguity (The Diamond Problem)
Ambiguity arises when a class inherits member functions with the same name from two or more base classes, causing the compiler to be unsure which function to invoke.
Avoid Ambiguity Using Scope Resolution Operator
The ambiguity can be resolved by using the scope resolution operator to specify the class in which the member function lies:
object.class_name::method_name();
class A {
public:
void func() {
cout << " I am A" << endl;
}
};
class B {
public:
void func() {
cout << " I am B" << endl;
}
};
class C: public A, public B {
};
int main() {
C obj;
obj.A::func();
obj.B::func();
return 0;
}
Using the virtual
keyword during inheritance avoids creating multiple copies of the same named variable/method.
Hybrid Inheritance in C++ with Diamond Problem and its Resolution | Virtual Inheritance in C++
Polymorphism [Very Important]
The term "Polymorphism
" is derived from the Greek words "poly" + "morphs," meaning many forms.
For example, a woman behaves like a teacher in a classroom, a mother or daughter at home, and a customer in a market. A single person is behaving differently in various situations.
Compile-Time Polymorphism
Function Overloading
When there are multiple functions with the same name but different parameters, these functions are said to be overloaded.class Geeks { public: void func(int x) { cout << "value of x is " << x << endl; } void func(double x) { cout << "value of x is " << x << endl; } void func(int x, int y) { cout << "value of x and y is " << x << ", " << y << endl; } }; int main() { Geeks obj1; obj1.func(7); obj1.func(9.132); obj1.func(85, 64); return 0; }
Operator Overloading
C++ allows overloading operators with special meanings for a data type.class Complex { private: int real, imag; public: Complex(int r = 0, int i = 0) { real = r; imag = i; } Complex operator+(Complex const& obj) { Complex res; res.real = real + obj.real; res.imag = imag + obj.imag; return res; } void print() { cout << real << " + i" << imag << endl; } }; int main() { Complex c1(10, 5), c2(2, 4); Complex c3 = c1 + c2; c3.print(); // 12 + i9 cout << 3 + 4<< endl; // 7 }
Runtime Polymorphism
(Method Overriding)
A child class can provide its own version of an implementation without altering the original function.
class Animal {
public:
void speak() {
cout << "Speaking " << endl;
}
};
class Dog: public Animal {
public:
void speak() {
cout << "Barking " << endl;
}
};
int main() {
Dog d;
d.speak(); // Barking
}
class Animal {
public:
void speak() {
cout << "Speaking " << endl;
}
};
class Dog: public Animal {
public:
void speak() {
cout << "Barking " << endl;
}
};
int main() {
Dog d;
d.speak(); // Barking
}
Virtual functions, abstract classes (pure virtual functions), method overriding, compile-time vs. runtime polymorphism.
Abstract Class
An abstract class is a class that can’t be instantiated directly. These classes exist to serve as base classes for other derived classes. Abstract classes contain at least one pure virtual function.
💡 We cannot create an object of an abstract class.
class Animal {
public:
virtual void sound() = 0; // Pure Virtual Function
};
class Dog: public Animal {
public:
void sound() {
cout << "Bark" << endl;
}
};
Why Use Abstract Classes?
Code Reusability: You can define common functionalities in the abstract class and extend them in derived classes.
Runtime Polymorphism: Achieved using function overriding in derived classes.
Pure Virtual Functions and Abstract Classes
Friend Function
In C++, a friend
function is a special function that can access the private and protected data members of a class.
💡 Friend
functions are not members of the class but have the privilege to access private data.
class Box {
private:
int length;
public:
Box() : length(0) {}
friend int printLength(Box);
};
int printLength(Box b) {
b.length += 10;
return b.length;
}
When to use friend functions:
If a function is not part of the class's functionality but needs to access its private or protected data.
To enable operator overloading when the left operand is not an object of the class.
class Box {
private:
int length;
public:
Box() : length(0) {}
friend void setLength(Box&, int len);
void displayLength() { cout << length << endl; }
};
void setLength(Box& b, int len) {
b.length = len;
}
Destructor
A destructor is a special member function that is executed whenever an object of its class goes out of scope or is explicitly deleted.
class Person {
public:
// Constructor
Person() {
cout << "Constructor is called." << endl;
}
// Destructor
~Person() {
cout << "Destructor is called." << endl;
}
};
int main() {
Person p1;
return 0;
}
The
delete
keyword is used to deallocate memory and calls the destructor.
Virtual Destructor
When we delete a derived class object using a base class pointer, the behavior is undefined if the destructor in the base class is not virtual.
class Base {
public:
virtual ~Base() {
cout << "Base class destructor called" << endl;
}
};
class Derived : public Base {
public:
~Derived() {
cout << "Derived class destructor called" << endl;
}
};
int main() {
Base *b = new Derived();
delete b;
return 0;
}
Abstraction Vs Encapsulation
Abstraction is generalized term. i.e. Encapsulation is subset of Abstraction.
Abstraction | Encapsulation |
It solves an issue at the design level. | Encapsulation solves an issue at implementation level. |
hides the unnecessary detail but shows the essential information. | It hides the code and data into a single entity or unit so that the data can be protected from the outside world. |
Focuses on the external lookout. | Focuses on internal working. |
Lets focus on what an object does instead of how it does it. | Lets focus on how an object does something. |
Example: Outer look of mobile, like it has a display screen and buttons. | Example: Inner details of mobile, how button and display screen connect with each other using circuits. |
https://stackoverflow.com/questions/742341/difference-between-abstraction-and-encapsulation