Encapsulation and Abstraction in C++
Encapsulation and abstraction are two of the four pillars of Object-Oriented Programming. Together they protect data, simplify interfaces, and help build secure and maintainable software systems.
Encapsulation
Encapsulation means wrapping data and the functions that operate on it together, and controlling access to internal details. Think of it like a medicine capsule — the active ingredients are hidden inside; users just take the capsule without knowing its chemical composition.
In C++, encapsulation is achieved by:
- Making data members
private - Providing
publicgetter and setter methods for controlled access
Without Encapsulation (risky):
class Account {
public:
double balance; // anyone can directly change it!
};
int main() {
Account a;
a.balance = -99999; // no validation — dangerous
return 0;
}
With Encapsulation (safe):
#include <iostream>
using namespace std;
class Account {
private:
double balance; // hidden from outside
public:
void deposit(double amount) {
if (amount > 0)
balance += amount;
}
void withdraw(double amount) {
if (amount > 0 && amount <= balance)
balance -= amount;
else
cout << "Invalid withdrawal." << endl;
}
double getBalance() {
return balance;
}
Account() { balance = 0; }
};
int main() {
Account myAcc;
myAcc.deposit(5000);
myAcc.withdraw(2000);
cout << "Balance: " << myAcc.getBalance() << endl;
return 0;
}
Output:
Balance: 3000Benefits of Encapsulation
- Data protection — Prevents unauthorized access and invalid modifications.
- Flexibility — Internal implementation can change without affecting external code.
- Reusability — Well-encapsulated classes are easier to reuse.
- Debugging — Bugs are easier to isolate when data access is controlled.
Abstraction
Abstraction means showing only what is necessary and hiding the complex details. A user of a class should not need to know how it works internally — only what it can do.
Real-life example: A TV remote has buttons for volume and channels. The user does not need to know the electronics inside — just press the button and it works. The complexity is hidden; the interface is simple.
Abstraction through Access Specifiers:
class TV {
private:
int channel;
int volume;
bool powerOn;
void tuneSignal() {
// complex internal tuning logic hidden here
}
public:
TV() : channel(1), volume(10), powerOn(false) {}
void turnOn() { powerOn = true; cout << "TV ON" << endl; }
void turnOff() { powerOn = false; cout << "TV OFF" << endl; }
void setChannel(int ch) { channel = ch; tuneSignal(); }
void setVolume(int v) { if (v >= 0 && v <= 100) volume = v; }
void status() {
cout << "Channel: " << channel << " Volume: " << volume << endl;
}
};
int main() {
TV myTV;
myTV.turnOn();
myTV.setChannel(5);
myTV.setVolume(20);
myTV.status();
myTV.turnOff();
return 0;
}
Output:
TV ON
Channel: 5 Volume: 20
TV OFFAbstraction through Abstract Classes
An abstract class defines an interface with pure virtual functions. Derived classes provide the actual implementation.
class Shape {
public:
virtual double area() = 0; // pure virtual — must be implemented
virtual void display() = 0;
};
class Circle : public Shape {
double radius;
public:
Circle(double r) : radius(r) {}
double area() override { return 3.14 * radius * radius; }
void display() override { cout << "Circle area: " << area() << endl; }
};
class Rectangle : public Shape {
double l, w;
public:
Rectangle(double l, double w) : l(l), w(w) {}
double area() override { return l * w; }
void display() override { cout << "Rectangle area: " << area() << endl; }
};
int main() {
Shape *s;
s = new Circle(5); s->display();
s = new Rectangle(4,6); s->display();
return 0;
}
Output:
Circle area: 78.5
Rectangle area: 24Encapsulation vs Abstraction
| Concept | Focus | How |
|---|---|---|
| Encapsulation | Data hiding and protection | Private members + public methods |
| Abstraction | Hiding complexity; showing interface | Abstract classes + virtual functions |
Key Takeaways
- Encapsulation wraps data and methods together and restricts direct access.
- Private data + public getter/setter methods is the standard encapsulation pattern.
- Abstraction exposes only the essential interface and hides internal complexity.
- Abstract classes with pure virtual functions define strict interfaces for derived classes.
