Tutorials Logic, IN info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Website Development
Practice
Quiz Challenge Interview Questions Certification Practice
Tools
Online Compiler JSON Formatter Regex Tester CSS Unit Converter Color Picker
Compiler Tools

C++ Abstraction Abstract Classes Interfaces: Tutorial, Examples, FAQs & Interview Tips

What is Abstraction?

Abstraction means hiding complex implementation details and exposing only the essential interface. In C++, abstraction is achieved through abstract classes and pure virtual functions.

  • A pure virtual function is declared with = 0 - it has no implementation in the base class.
  • A class with at least one pure virtual function is an abstract class - you cannot instantiate it directly.
  • Derived classes must override all pure virtual functions to be instantiable.
Abstract Class and Pure Virtual Functions
#include <iostream>
#include <string>
using namespace std;

// Abstract class - cannot be instantiated
class PaymentMethod {
public:
    // Pure virtual functions - MUST be overridden
    virtual bool processPayment(double amount) = 0;
    virtual string getType() const = 0;

    // Concrete method - shared by all derived classes
    void printReceipt(double amount) {
        if (processPayment(amount)) {
            cout << "[" << getType() << "] Payment of $"
                 << amount << " successful." << endl;
        } else {
            cout << "[" << getType() << "] Payment failed." << endl;
        }
    }

    virtual ~PaymentMethod() {}
};

class CreditCard : public PaymentMethod {
    double limit;
public:
    CreditCard(double limit) : limit(limit) {}

    bool processPayment(double amount) override {
        return amount <= limit;
    }
    string getType() const override { return "Credit tl-card"; }
};

class PayPal : public PaymentMethod {
    double balance;
public:
    PayPal(double balance) : balance(balance) {}

    bool processPayment(double amount) override {
        if (amount <= balance) { balance -= amount; return true; }
        return false;
    }
    string getType() const override { return "PayPal"; }
};

int main() {
    // PaymentMethod pm;  // ERROR: cannot instantiate abstract class

    PaymentMethod *methods[] = {
        new CreditCard(1000),
        new PayPal(50)
    };

    methods[0]->printReceipt(200);   // Credit Card: success
    methods[1]->printReceipt(200);   // PayPal: failed (only $50)

    for (auto m : methods) delete m;
    return 0;
}

Interface Pattern (Pure Abstract Class)

A class with only pure virtual functions acts as an interface - it defines a contract that all implementing classes must fulfill.

Interface Pattern
#include <iostream>
using namespace std;

// Interface (pure abstract class)
class ILogger {
public:
    virtual void log(const string &msg) = 0;
    virtual void error(const string &msg) = 0;
    virtual ~ILogger() {}
};

class ConsoleLogger : public ILogger {
public:
    void log(const string &msg) override {
        cout << "[LOG]   " << msg << endl;
    }
    void error(const string &msg) override {
        cerr << "[ERROR] " << msg << endl;
    }
};

class FileLogger : public ILogger {
public:
    void log(const string &msg) override {
        // In real code: write to file
        cout << "[FILE LOG]   " << msg << endl;
    }
    void error(const string &msg) override {
        cout << "[FILE ERROR] " << msg << endl;
    }
};

void runApp(ILogger &logger) {
    logger.log("Application started");
    logger.error("Something went wrong");
}

int main() {
    ConsoleLogger cl;
    FileLogger    fl;

    runApp(cl);  // uses ConsoleLogger
    runApp(fl);  // uses FileLogger - same function, different behaviour

    return 0;
}

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.