# Inheritance, Interfaces and Polymorphism — C#/.NET

Source: https://www.skillbyai.com/en/dotnet/o-inherit

> Use abstract classes, virtual methods and interfaces appropriately.

## Two ways to share behaviour

A class can **inherit** from one base class and gets its members. Methods marked **`virtual`** can be replaced in a derived class with **`override`**; **`abstract`** methods have no body and must be overridden, and an `abstract` class cannot be instantiated. **`sealed`** stops further inheritance. **Interfaces** define a contract that any class or struct can implement, and a type can implement **many** interfaces; interfaces can also contain **default implementations** and static abstract members (used for generic math). **Polymorphism** means code written against a base type or interface works with any implementation, and the runtime calls the most-derived override. Prefer interfaces and composition for flexibility; use inheritance for genuine *is-a* relationships with shared implementation. Beware `new` on a member: it **hides** the base member instead of overriding it, so behaviour depends on the variable's static type.

## Interface-based payment providers

The checkout code depends only on the interface, so a new provider needs no change to it.

```cs
public interface IPaymentProvider
{
    string Name { get; }
    Task<bool> ChargeAsync(decimal amount, CancellationToken ct = default);
}

public abstract class PaymentProviderBase : IPaymentProvider
{
    public abstract string Name { get; }
    public async Task<bool> ChargeAsync(decimal amount, CancellationToken ct = default)
    {
        if (amount <= 0) return false;
        return await ChargeCoreAsync(amount, ct);
    }
    protected abstract Task<bool> ChargeCoreAsync(decimal amount, CancellationToken ct);
}

public sealed class UpiProvider : PaymentProviderBase
{
    public override string Name => "UPI";
    protected override Task<bool> ChargeCoreAsync(decimal amount, CancellationToken ct) =>
        Task.FromResult(true);   // call the real gateway here
}
```

## Charging ports

An interface is like a USB-C port specification. Any charger that follows the spec works with your phone, whichever company made it. Inheritance is more like a family resemblance: useful, but you only get one set of parents.

**Quiz:** A class needs behaviour from two unrelated contracts. What does C# allow?

- [ ] Inheriting from two base classes
- [ ] Neither; C# allows only one of each
- [ ] Using the new keyword on both
- [x] Implementing two interfaces

*Answer:* Implementing two interfaces. C# supports single class inheritance but multiple interface implementation.
