Introduction
Abstraction is one of the fundamental principles of Object-Oriented Programming (OOP) in C++. It allows you to define complex systems in a simplified manner by focusing on the essential characteristics while hiding the unnecessary details. Abstraction is achieved using abstract classes and interfaces.
Abstract Classes
An abstract class in C++ is a class that cannot be instantiated. It is designed to be a base class from which other classes are derived. An abstract class contains at least one pure virtual function.
Pure Virtual Functions
A pure virtual function is a function that has no implementation in the base class and must be overridden in any derived class. It is declared by assigning 0 to the function declaration.
Syntax for Abstract Classes and Pure Virtual Functions
class AbstractClass {
public:
virtual void pureVirtualFunction() = 0; // Pure virtual function
};
Example: Abstract Class and Pure Virtual Function
#include <iostream>
using namespace std;
// Abstract base class
class Shape {
public:
// Pure virtual function
virtual void draw() = 0;
// Normal member function
void description() {
cout << "This is a shape." << endl;
}
};
// Derived class
class Circle : public Shape {
public:
void draw() override {
cout << "Drawing Circle" << endl;
}
};
// Another derived class
class Rectangle : public Shape {
public:
void draw() override {
cout << "Drawing Rectangle" << endl;
}
};
int main() {
Circle circle;
Rectangle rectangle;
// Drawing shapes
circle.draw();
rectangle.draw();
// Description of shapes
circle.description();
rectangle.description();
return 0;
}
Output
Drawing Circle
Drawing Rectangle
This is a shape.
This is a shape.
Explanation
Shapeis an abstract class with a pure virtual functiondraw.CircleandRectangleare derived classes that override thedrawfunction.- The
descriptionfunction is a normal member function in theShapeclass that is inherited byCircleandRectangle.
Abstract Classes in Action
Abstract classes are used to define interfaces for a set of related classes, enforcing a contract that derived classes must follow. This allows for a clear and consistent design.
Example: Vehicle Abstraction
#include <iostream>
using namespace std;
// Abstract base class
class Vehicle {
public:
// Pure virtual function
virtual void startEngine() = 0;
// Normal member function
void description() {
cout << "This is a vehicle." << endl;
}
};
// Derived class
class Car : public Vehicle {
public:
void startEngine() override {
cout << "Starting car engine" << endl;
}
};
// Another derived class
class Motorcycle : public Vehicle {
public:
void startEngine() override {
cout << "Starting motorcycle engine" << endl;
}
};
int main() {
Car car;
Motorcycle motorcycle;
// Starting engines
car.startEngine();
motorcycle.startEngine();
// Description of vehicles
car.description();
motorcycle.description();
return 0;
}
Output
Starting car engine
Starting motorcycle engine
This is a vehicle.
This is a vehicle.
Explanation
Vehicleis an abstract class with a pure virtual functionstartEngine.CarandMotorcycleare derived classes that override thestartEnginefunction.- The
descriptionfunction is a normal member function in theVehicleclass that is inherited byCarandMotorcycle.
Interfaces in C++
While C++ does not have a distinct keyword for interfaces like some other programming languages, abstract classes with only pure virtual functions can effectively serve as interfaces.
Example: Interface in C++
#include <iostream>
using namespace std;
// Interface
class IShape {
public:
virtual void draw() = 0; // Pure virtual function
virtual double area() = 0; // Pure virtual function
};
// Implementing the interface
class Circle : public IShape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
void draw() override {
cout << "Drawing Circle" << endl;
}
double area() override {
return 3.14 * radius * radius;
}
};
// Another implementation
class Rectangle : public IShape {
private:
double length;
double width;
public:
Rectangle(double l, double w) : length(l), width(w) {}
void draw() override {
cout << "Drawing Rectangle" << endl;
}
double area() override {
return length * width;
}
};
int main() {
Circle circle(5);
Rectangle rectangle(4, 6);
// Drawing shapes
circle.draw();
rectangle.draw();
// Calculating areas
cout << "Circle Area: " << circle.area() << endl;
cout << "Rectangle Area: " << rectangle.area() << endl;
return 0;
}
Output
Drawing Circle
Drawing Rectangle
Circle Area: 78.5
Rectangle Area: 24
Explanation
IShapeis an interface with pure virtual functionsdrawandarea.CircleandRectangleimplement theIShapeinterface by providing definitions for thedrawandareafunctions.
Example Programs
Example 1: Employee Management System
#include <iostream>
using namespace std;
// Abstract base class
class Employee {
public:
virtual void work() = 0; // Pure virtual function
void description() {
cout << "This is an employee." << endl;
}
};
// Derived class
class Developer : public Employee {
public:
void work() override {
cout << "Writing code" << endl;
}
};
// Another derived class
class Manager : public Employee {
public:
void work() override {
cout << "Managing team" << endl;
}
};
int main() {
Developer dev;
Manager mgr;
dev.work();
mgr.work();
dev.description();
mgr.description();
return 0;
}
Output
Writing code
Managing team
This is an employee.
This is an employee.
Explanation
Employeeis an abstract class with a pure virtual functionwork.DeveloperandManagerare derived classes that override theworkfunction.- The
descriptionfunction is a normal member function in theEmployeeclass that is inherited byDeveloperandManager.
Example 2: Appliance Control System
#include <iostream>
using namespace std;
// Abstract base class
class Appliance {
public:
virtual void turnOn() = 0; // Pure virtual function
virtual void turnOff() = 0; // Pure virtual function
void description() {
cout << "This is an appliance." << endl;
}
};
// Derived class
class Fan : public Appliance {
public:
void turnOn() override {
cout << "Fan is now ON" << endl;
}
void turnOff() override {
cout << "Fan is now OFF" << endl;
}
};
// Another derived class
class Light : public Appliance {
public:
void turnOn() override {
cout << "Light is now ON" << endl;
}
void turnOff() override {
cout << "Light is now OFF" << endl;
}
};
int main() {
Fan fan;
Light light;
fan.turnOn();
fan.turnOff();
light.turnOn();
light.turnOff();
fan.description();
light.description();
return 0;
}
Output
Fan is now ON
Fan is now OFF
Light is now ON
Light is now OFF
This is an appliance.
This is an appliance.
Explanation
Applianceis an abstract class with pure virtual functionsturnOnandturnOff.FanandLightare derived classes that override theturnOnandturnOfffunctions.- The
descriptionfunction is a normal member function in theApplianceclass that is inherited byFanandLight.
Conclusion
Abstraction in C++ allows you to define complex systems by focusing on essential characteristics and hiding unnecessary details. This chapter covered the implementation of abstraction using abstract classes and pure virtual functions. Example programs demonstrated the use of abstraction in different contexts. Understanding and implementing abstraction effectively is crucial for creating robust and maintainable object-oriented programs.