π Default Interface Methods = API Evolution
Interfaces break existing code. Default interface methods add methods without breaking. Evolve APIs safely.
π Default Interface Basics
// Interface with default method
public interface ILogger
{
void Log(string message);
// Default implementation
void LogError(string message)
{
Log($"ERROR: {message}");
}
// Default implementation
void LogWarning(string message)
{
Log($"WARNING: {message}");
}
}
// Implementation
public class ConsoleLogger : ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
}
// Usage - doesn't need to implement LogError
var logger = new ConsoleLogger();
logger.Log("Info");
logger.LogError("Something went wrong"); // Works!
// Override default
public class DatabaseLogger : ILogger
{
public void Log(string message)
{
// Write to database
}
public void LogError(string message)
{
// Custom error logging
Log($"CUSTOM ERROR: {message}");
}
}
π― Advanced Usage
// Static methods in interfaces
public interface IMath
{
static int Add(int a, int b) => a + b;
}
// Private methods in interfaces
public interface ICalculator
{
int Calculate(int a, int b);
private int Multiply(int a, int b) => a * b;
int Power(int a, int b)
{
int result = 1;
for (int i = 0; i < b; i++)
{
result = Multiply(result, a);
}
return result;
}
}
// Multiple inheritance
public interface ILoggable
{
void Log(string message);
void LogInfo(string message) => Log($"INFO: {message}");
}
public interface IAuditable
{
void Audit(string action);
void AuditCreate(string entity) => Audit($"CREATE: {entity}");
}
public class UserService : ILoggable, IAuditable
{
public void Log(string message) => Console.WriteLine(message);
public void Audit(string action) => Console.WriteLine(action);
// Both interfaces work
}
// Diamond problem - explicit implementation
public interface IA
{
void Method() => Console.WriteLine("A");
}
public interface IB
{
void Method() => Console.WriteLine("B");
}
public class C : IA, IB
{
public void Method()
{
// Must be implemented
Console.WriteLine("C");
}
}
π‘ Best Practices
- Use for API evolution
- Keep defaults simple
- Document default behavior
- Use sparingly (avoid complexity)
- Consider interface segregation
“Default interface methods enable safe API evolution. Add methods without breaking. Essential for library design.”
