Abstract Classes and Interfaces in C++
An abstract class is a class that has at least one pure virtual function. A pure virtual function is declared with = 0 at the end of its declaration. An abstract class cannot have its objects created, but it can be used as a pointer or reference type to support polymorphism.
An interface in C++ is a class whose members are all pure virtual functions. An interface defines the contract that must be fulfilled by all classes that inherit from it.
Code Example
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class PaymentProcessor {
public:
virtual bool processPayment(double amount) = 0;
virtual bool refundPayment(double amount) = 0;
virtual string getProcessorName() = 0;
virtual ~PaymentProcessor() {}
};
class CreditCardProcessor : public PaymentProcessor {
private:
string cardNumber;
string cardHolder;
public:
CreditCardProcessor(string card, string holder) : cardNumber(card), cardHolder(holder) {}
bool processPayment(double amount) override {
cout << "Processing credit card payment: $ " << amount << endl;
cout << "Card: ****" << cardNumber.substr(cardNumber.length() - 4) << endl;
return true;
}
bool refundPayment(double amount) override {
cout << "Credit card refund: $ " << amount << endl;
return true;
}
string getProcessorName() override {
return "Credit Card";
}
};
class BankTransferProcessor : public PaymentProcessor {
private:
string bankName;
string accountNumber;
public:
BankTransferProcessor(string bank, string account) : bankName(bank), accountNumber(account) {}
bool processPayment(double amount) override {
cout << "Bank transfer from " << bankName << ": $ " << amount << endl;
cout << "Account: " << accountNumber << endl;
return true;
}
bool refundPayment(double amount) override {
cout << "Bank transfer refund: $ " << amount << endl;
return true;
}
string getProcessorName() override {
return "Bank Transfer " + bankName;
}
};
class EWalletProcessor : public PaymentProcessor {
private:
string walletName;
public:
EWalletProcessor(string name) : walletName(name) {}
bool processPayment(double amount) override {
cout << "Payment " << walletName << ": $ " << amount << endl;
return true;
}
bool refundPayment(double amount) override {
cout << "Refund " << walletName << ": $ " << amount << endl;
return true;
}
string getProcessorName() override {
return walletName;
}
};
void checkout(PaymentProcessor* processor, double amount) {
cout << "=== Checkout ===" << endl;
cout << "Method: " << processor->getProcessorName() << endl;
if (processor->processPayment(amount)) {
cout << "Payment successful!" << endl;
} else {
cout << "Payment failed!" << endl;
}
cout << endl;
}
int main() {
CreditCardProcessor cc("1234567890123456", "John Smith");
BankTransferProcessor bt("ABC Bank", "1234567890");
EWalletProcessor ew("PayGo");
checkout(&cc, 500000);
checkout(&bt, 250000);
checkout(&ew, 100000);
cout << "=== Refund ===" << endl;
cc.refundPayment(100000);
bt.refundPayment(50000);
return 0;
}
Code Explanation
-
virtual bool processPayment(double amount) = 0- A pure virtual function. The= 0marks that this function has no implementation in the base class and must be implemented in the derived class. -
class PaymentProcessor- An abstract class because it has pure virtual functions. You cannot create an objectPaymentProcessor pp;but you can havePaymentProcessor* ptr;. -
class CreditCardProcessor : public PaymentProcessor- A concrete class that inherits from PaymentProcessor and implements all the pure virtual functions. -
virtual ~PaymentProcessor() {}- An empty virtual destructor in the abstract class. Important for proper cleanup through a base class pointer. -
void checkout(PaymentProcessor* processor, double amount)- A function that receives a pointer to an abstract class. It can receive a CreditCardProcessor, BankTransferProcessor, or EWalletProcessor object. -
processor->getProcessorName()- A dynamic virtual function call based on the actual object type passed to the function. -
All pure virtual functions must be implemented in the derived class for it to become a concrete class. Otherwise, the derived class is also abstract.
-
A C++ interface is a class whose members are all pure virtual functions. It has no concrete data members.
Everyday Use Cases
Imagine an automatic ticket machine at a station. The machine defines an interface: select a destination, pay, print a ticket. Each payment vendor (credit card, e-wallet, bank transfer) must follow the same interface. You do not need to know the details of how each vendor works — just send instructions through the same interface.
Conclusion
An abstract class has at least one pure virtual function and cannot have its objects created. An interface is a class whose members are all pure virtual functions. Use an abstract class when there is basic shared behavior among derived classes. Use an interface when you only define a contract without any implementation. A virtual destructor must exist in an abstract class for proper cleanup.