# Programming to Interfaces and Duck Typing — Object-Oriented Programming (OOP)

Source: https://www.skillbyai.com/en/oop/p-interfaces

> Depend on abstractions and compare nominal interfaces with duck typing.

## Depend on what, not on who

**Programming to an interface** means declaring variables, parameters and return types using abstract types (`List`, `PaymentGateway`) rather than concrete classes (`ArrayList`, `RazorpayGateway`). Code written against the interface works with any implementation, so you can swap implementations, add new ones and substitute **test doubles** without changing callers. Java and C# use **nominal typing**: a class must explicitly declare `implements PaymentGateway`. Python and JavaScript use **duck typing** ("if it walks like a duck and quacks like a duck"): any object with the right methods works, checked only when called. Python adds optional structure with **abstract base classes** (`abc.ABC`) and **protocols** (`typing.Protocol`), which type checkers verify **structurally**. Go interfaces are also structural: a type satisfies an interface simply by having its methods. Whatever the language, keep interfaces **small and focused** on what callers need.

## A payment interface, two implementations and a Python protocol

Checkout depends only on the abstraction.

```java
public interface PaymentGateway {
    PaymentResult charge(String orderId, long amountPaise);
}

public final class UpiGateway implements PaymentGateway {
    public PaymentResult charge(String orderId, long amountPaise) { /* call UPI provider */ return PaymentResult.ok(); }
}

public final class FakeGateway implements PaymentGateway {        // for tests
    public PaymentResult charge(String orderId, long amountPaise) { return PaymentResult.ok(); }
}

public final class Checkout {
    private final PaymentGateway gateway;                          // interface type
    public Checkout(PaymentGateway gateway) { this.gateway = gateway; }
    public PaymentResult pay(String orderId, long amount) { return gateway.charge(orderId, amount); }
}

// Python: structural typing with a Protocol
// from typing import Protocol
// class PaymentGateway(Protocol):
//     def charge(self, order_id: str, amount_paise: int) -> bool: ...
// any class with a matching charge() method is accepted by a type checker
```

## Interfaces belong to the caller

Design an interface from the point of view of the code that uses it, with only the methods it needs. A 30-method interface that mirrors one implementation is just a header file, not an abstraction.

**Quiz:** What is duck typing?

- [x] An object is usable if it has the required methods, regardless of its declared type
- [ ] A class must declare which interfaces it implements
- [ ] Only primitive types can be used
- [ ] A naming convention for Python classes

*Answer:* An object is usable if it has the required methods, regardless of its declared type. Duck typing checks behaviour (available methods) rather than declared type.
