C++ Abstraction

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

  • Shape is an abstract class with a pure virtual function draw.
  • Circle and Rectangle are derived classes that override the draw function.
  • The description function is a normal member function in the Shape class that is inherited by Circle and Rectangle.

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

  • Vehicle is an abstract class with a pure virtual function startEngine.
  • Car and Motorcycle are derived classes that override the startEngine function.
  • The description function is a normal member function in the Vehicle class that is inherited by Car and Motorcycle.

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

  • IShape is an interface with pure virtual functions draw and area.
  • Circle and Rectangle implement the IShape interface by providing definitions for the draw and area functions.

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

  • Employee is an abstract class with a pure virtual function work.
  • Developer and Manager are derived classes that override the work function.
  • The description function is a normal member function in the Employee class that is inherited by Developer and Manager.

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

  • Appliance is an abstract class with pure virtual functions turnOn and turnOff.
  • Fan and Light are derived classes that override the turnOn and turnOff functions.
  • The description function is a normal member function in the Appliance class that is inherited by Fan and Light.

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.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top