As we learned earlier about polymorphism.
We discovered:
Animal* animal = new Dog();
animal->makeSound();The code works because:
Animaldefines a contact, and:
Dogimplements that contract.
This introduces one of the most important idead in software engineering:
Good sofrware depedns on contracts, not concrete implementation.
This idea is responsible for:
Modern Frameworks
Plugin Architectures
Microservices SDKs
Cloud SDKs
Database Drivers
Payment Gateways
Operating Systems
Game Engines
Enterprise SoftwareWithout contracts, software becomes:
Rigid
Tightly Coupled
Difficult To Test
Difficult To ExtendWith contracts, software becomes:
Flexible
Replaceable
Extensible
MaintainableThe Fundamental Problem
Imagine building:
Food Delivery System
You create:
class EmailService
{
public:
void sendEmail()
{
}
};Then:
class OrderService {
private:
EmailService: emailService;
};Looks fine.
Later requiremnts change:
Need SMS
Need WhatsApp
Need Push Notifications
Need Slack NotificationsNow:
OrderServiceis tightly coupled to:
EmailServiceThis is a common enterprise problem.
What Is a Contract?
A contract defines:
What must be donewithout specifying:
How it is doneExample:
Payment Gateway Contract
Must Support:
Pay()
Refund()Contract says:
WhatNot:
HowDifferent implementations:
Stripe
Razorpay
PayPal
UPIcan all satisfy the same contract.
Real-World Analogy
Consider a wall socket.
The socket defines:
Voltage
Frequency
Plug ShapeThe socket does NOT care whether the connected device is:
Laptop
Phone Charger
Television
PrinterThe socket represents:
Interface
Device represent:
ImplementationsThis is contract-based design.
What Is an Interface?
Conceptual Definition
An interface defines:
A set of operations that must be provided.
In many languages:
Java
C#
TypeScriptthere is a dedicated interface keyword.
C++ traditionally uses:
Pure Abstract Classesto implement interfaces.
First Interface Example
Class IPaymentMethod
{
public:
virtual void pay() = 0;
virtual ~IPaymentMethod() = default;
};Notice:
= 0This makes the method:
Pure VirtualMeaning:
Must be ImplementedImplementing the Interface
class CreditCardPayment :
public IPaymentMethod
{
public:
void pay() override
{
cout << "Credit Card Payment";
}
};Another implementation:
class UpiPayment :
public IPaymentMethod
{
public:
void pay() override
{
cout << "UPI Payment";
}
};Both satisfy:
IPaymentMethodcontract.
Using the Interface
void processPayment(
IPaymentMethod& payment)
{
payment.pay();
}Usage:
CreditCardPayment card;
processPayment(card);Later:
UpiPayment upi;
processPayment(upi);No code changes required.
The Power of Abstraction
Without abstraction:
void processPayment(
CreditCardPayment& payment)
{
}Only supports:
CreditCardPaymentWith abstraction:
void processPayment(
IPaymentMethod& payment)
{
}Supports:
Any Payment MethodThis dramatically improves extensibility.
What Is an Abstract Class?
An abstract class is:
A class that cannot be instantiated directly.
Example:
class Animal
{
public:
virtual void makeSound() = 0;
};Invalid:
Animal animal;Valid:
Dog dog;
Cat cat;Abstract classes exist to define common behavior.
Interface vs Abstract Class
Many beginners confuse these concepts.
Interface
Contains:
Contract OnlyExample:
class ILogger
{
public:
virtual void log() = 0;
virtual ~ILogger() = default;
};No state.
No implementation.
Purpose:
Pure ContractAbstract Class
Can contain:
State
Implementation
Abstract MethodsExample:
class Animal
{
protected:
string name;
public:
virtual void makeSound() = 0;
void sleep()
{
cout << "Sleeping";
}
};Contains:
Data
Behavior
ContractComparison Table
| Feature | Interface | Abstract Class |
|---|---|---|
| Instantiable | No | No |
| State | Usually No | Yes |
| Implementation | Usually No | Yes |
| Contract Definition | Yes | Yes |
| Shared Logic | No | Yes |
| Primary Purpose | Behavior Contract | Common Base Functionality |
UML Representation
Interface:
<<interface>>
IPaymentMethod
-----------------
pay()Implementation:
<<interface>>
IPaymentMethod
▲
|
--------------------
| |
CreditCard UpiPaymentAbstract Class:
<<abstract>>
Animal
-----------------
sleep()
makeSound()Why Interfaces Matter
Imagine:
Database LayerBad Design:
class UserService
{
private:
MySQLDatabases db;
};Problem:
Switching to:
PostgreSQL
MongoDB
SQLiterequires code changes.
Better:
class IDatabase
{
public:
virtual void save() = 0;
};Implementations:
MySQLDatabase
PostgreDatabase
MongoDatabaseNow:
UserServicedepends on:
IDatabaseinstead of:
MySQLDatabaseHuge improvement.
Programming to Abstraction
One of the most famous design principles.
Bad:
MySQLDatabase database;Better:
IDatabase& database;Bad:
CreditCardPayment payment;Better:
IPaymentMethod& payment;Rule:
Depend on what something does, not what it is.
Dependency Direction
Bad architecture:
OrderService
↓
EmailServiceOrderService depends on EmailService.
Better:
OrderService
↓
INotificationService
↑
EmailServiceNow:
EmailService
SmsService
WhatsAppServicecan all be substituted.
Extensibility Example
Requirement:
Add Slack NotificationBad Design:
Modify:
OrderServiceGood Design:
Create:
class SlackNotification
: public INotificationService
{
};Done.
No existing code changes.
This is professional design.
Testing Benefits
Interfaces dramatically improve testing.
Example:
class IEmailService
{
public:
virtual void send() = 0;
};Production:
EmailServiceTesting:
FakeEmailServiceNo real emails sent.
Testing becomes easier.
This is why interfaces dominate enterprise systems.
Common Interface Naming Convention
Common C++ style:
ILogger
IDatabase
IPaymentGateway
INotificationServicePrefix:
Iindicates interface.
Not mandatory.
But common.
Interface Segregation Preview
Bad:
class IWorker
{
public:
virtual void work() = 0;
virtual void eat() = 0;
virtual void sleep() = 0;
virtual void drive() = 0;
virtual void fly() = 0;
};Huge interface.
Many classes need only part of it.
This violates:
Interface Segregation Principle
Common Beginner Mistakes
Mistake 1
Depending on Concrete Classes
PaymentProcessor
↓
StripePaymentToo rigid.
Prefer:
PaymentProcessor
↓
IPaymentMethodMistake 2
Creating interfaces for Everything
Not every class needs an interface.
Example:
Point
Rectangle
DateUsually do not need interfaces.
Use interfaces where variation is expected.
Mistake 3
Huge Interfaces
100+ MethodsUsually poor design.
Interfaces should be focused.
Mistake 4:
Leaking Implementation Details
Bad:
class IDatabase
{
public:
virtual MySQLConnection*
getConnection() = 0;
};Now interface depends on MySQL.
Defeats abstraction.
Industry Perspective
Large-scale systems rely heavily on interfaces.
Examples:
Spring Framework
ASP.NET
Qt
Unreal Engine
AWS SDK
Azure SDK
Database Drivers
Cloud Storage SystemsWhy?
Because large systems must support:
Replacement
Testing
Evolution
ExtensionInterfaces make this possible.
Expert Notes
One of the biggest mindset shifts:
Beginner thinks:
What class should I use?Senior engineer thinks:
What contract should exist?Another insight:
Interfaces are not about implementation.
They are about boundaries.

Join the discussion
Sign in with your account to post comments, reply to others, and participate in the conversation.
Login to Comment