Interfaces & Abstract Classes

17 questions found

An abstract class can hold state and shared implementation and supports single inheritance; an interface is a contract a type can implement many of. Use interfaces for capabilities, abstract classes for a shared base.
public interface IPayable { decimal Pay(); }
public abstract class Employee : IPayable { public string Name=""; public abstract decimal Pay(); }
Real-world example IPayable expresses the capability; Employee shares Name across subtypes.
Depending on an abstraction decouples callers from implementations, enabling substitution, testing with mocks, and dependency injection.
public OrderService(IOrderRepository repo) { }
Real-world example Swapping a SQL repository for an in-memory fake in unit tests without changing OrderService.
Since C# 8 an interface can provide a default method body, letting you add members to an interface without breaking existing implementers.
interface ILogger { void Log(string m); void LogError(string m) => Log("ERR: "+m); }
Real-world example Extending a widely-implemented library interface without forcing every implementer to change.
Yes. If signatures clash you can implement the members explicitly, qualified by interface name, so each interface gets its own behaviour accessible via that interface type.
class C : IA, IB { void IA.Do(){} void IB.Do(){} }
Real-world example Explicit implementation hides a rarely-used interface method from the public surface.
When you need shared state or non-trivial common implementation, versioning with protected members, or to control the construction of derived types — things interfaces cannot express as cleanly.
public abstract class HttpHandlerBase { protected readonly HttpClient Http; ... }
Real-world example A framework base class that provides plumbing and calls abstract hooks (template method pattern).
Clients should not depend on methods they do not use; prefer several small, focused interfaces over one large one, so implementers and consumers stay decoupled.
// instead of IRepository with 20 methods:
interface IReadRepository<T> { Task<T?> GetAsync(int id); }
Real-world example Splitting a fat service interface so a read-only consumer needn't depend on write methods.
An interface defines a CONTRACT of members (methods, properties, events, indexers) that implementing classes/structs must provide — traditionally, an interface couldn't contain ANY implementation, only signatures, though modern C# (8+) allows optional default implementations too.
public interface IShape {
  double CalculateArea(); // no implementation, just a contract
  double Perimeter { get; } // property signature only
}
public class Circle : IShape {
  public double Radius { get; set; }
  public double CalculateArea() => Math.PI * Radius * Radius;
  public double Perimeter => 2 * Math.PI * Radius;
}
Real-world example Defining a common IShape contract that Circle, Square, and Triangle all implement independently.

Common follow-ups: Can a class implement MULTIPLE interfaces at once, unlike single inheritance from a base class?

OOP
An abstract class CANNOT be instantiated directly with 'new' and can contain a mix of concrete (implemented) members AND abstract members (declared but not implemented, requiring subclasses to provide them) — it's meant purely as a base to be extended, unlike a regular concrete class which CAN be instantiated on its own.
public abstract class Animal {
  public string Name { get; set; } = "";
  public abstract void MakeSound(); // must be implemented by subclasses
  public void Sleep() => Console.WriteLine($"{Name} is sleeping."); // shared, concrete implementation
}
// new Animal(); // Error: cannot instantiate an abstract class
Real-world example Defining a shared Animal base class with common behavior (Sleep) plus a required, subclass-specific behavior (MakeSound).

Common follow-ups: Can an abstract class have a constructor, even though it can never be instantiated directly?

Records & Pattern Matching
Use an abstract class when subclasses genuinely SHARE common implementation/state and there's a clear 'is-a' hierarchy (a class can only extend ONE abstract class); use an interface when you need to define a CAPABILITY/CONTRACT that unrelated classes can all implement independently (a class can implement MANY interfaces) — interfaces express 'can-do' relationships, abstract classes express 'is-a' relationships.
// Interface: unrelated types sharing a CAPABILITY
public interface IFlyable { void Fly(); }
public class Bird : IFlyable { public void Fly() { } }
public class Airplane : IFlyable { public void Fly() { } }

// Abstract class: related types sharing an IDENTITY and implementation
public abstract class Animal { public abstract void MakeSound(); }
Real-world example Choosing an interface for a cross-cutting capability like ISerializable, versus an abstract class for a genuine domain hierarchy like Animal -> Dog.

Common follow-ups: Can an abstract class ALSO implement one or more interfaces, combining both approaches?

OOP
A default interface method provides a BODY directly in the interface declaration, so implementing classes AUTOMATICALLY inherit that behavior unless they choose to override it — this specifically solves the problem of adding a NEW method to an existing, widely-implemented interface (like adding a method to IEnumerable<T>) without BREAKING every existing implementation that doesn't have it yet.
public interface ILogger {
  void Log(string message);
  void LogError(string message) => Log($"ERROR: {message}"); // default implementation, C# 8+
}
public class ConsoleLogger : ILogger {
  public void Log(string message) => Console.WriteLine(message);
  // LogError is inherited automatically -- no need to implement it
}
Real-world example Adding a new convenience method to a widely-used library interface without breaking every existing implementing class.

Common follow-ups: Can a class that implements the interface still choose to OVERRIDE a default interface method's implementation?

Records & Pattern Matching

Showing 1–10 of 17