Интерфейсы в C#

Интерфейсы в C#: контракт без реализации, implements, разница с абстрактным классом, default-методы.

Интерфейс — контракт: набор методов и свойств без реализации, которые класс обязуется предоставить. В C# интерфейс объявляется ключевым словом interface.

Объявление и реализация

interface IShape
{
    double Area();
    double Perimeter();
    void Describe();
}

class Circle : IShape
{
    private double _r;
    public Circle(double r) { _r = r; }

    public double Area() => Math.PI * _r * _r;
    public double Perimeter() => 2 * Math.PI * _r;
    public void Describe() =>
        Console.WriteLine($"Круг r={_r}: S={Area():F2}, P={Perimeter():F2}");
}

class Square : IShape
{
    private double _a;
    public Square(double a) { _a = a; }

    public double Area() => _a * _a;
    public double Perimeter() => 4 * _a;
    public void Describe() =>
        Console.WriteLine($"Квадрат a={_a}: S={Area():F2}, P={Perimeter():F2}");
}

IShape[] shapes = { new Circle(5), new Square(4) };
foreach (var s in shapes)
    s.Describe();

Вывод:

Круг r=5: S=78.54, P=31.42
Квадрат a=4: S=16.00, P=16.00

Несколько интерфейсов

Класс в C# может наследовать только один класс, но реализовать несколько интерфейсов одновременно:

interface IExportable
{
    string ToJson();
}

interface IPrintable
{
    void Print();
}

class Report : IExportable, IPrintable
{
    public string Title { get; set; }

    public string ToJson() => $"{{\"title\":\"{Title}\"}}";
    public void Print()    => Console.WriteLine($"Отчёт: {Title}");
}

var r = new Report { Title = "Квартальный" };
r.Print();
Console.WriteLine(r.ToJson());

Вывод:

Отчёт: Квартальный
{"title":"Квартальный"}

Интерфейс vs Абстрактный класс

Интерфейс

Абстрактный класс

Наследование

несколько интерфейсов

один базовый класс

Поля

нет

есть

Реализация методов

только default-методы (C# 8+)

обычные и абстрактные

Смысл

«умеет делать X»

«является Y»

Используйте интерфейс, когда хотите описать способность, которую могут иметь несвязанные классы. Используйте абстрактный класс, когда у классов общая природа и общий код.

Коротко

  • Интерфейс — контракт: только сигнатуры без реализации (кроме default-методов C# 8+).
  • Класс реализует интерфейс через двоеточие: class Foo : IBar.
  • Можно реализовать несколько интерфейсов; наследовать — только один класс.
  • Интерфейс = «умеет»; абстрактный класс = «является».
Проверьте себя
1. Сколько интерфейсов может реализовать один класс в C#?
AТолько один
BНе более двух
CНесколько — столько, сколько нужно
DНи одного
2. Чем интерфейс отличается от абстрактного класса?
AИнтерфейс быстрее работает
BИнтерфейс не имеет полей и реализаций методов (кроме default); можно реализовать несколько
CИнтерфейс нельзя использовать как тип переменной
DРазницы нет — это синонимы
3. Класс, реализующий интерфейс, обязан...
AОбъявить те же поля, что и в интерфейсе
BРеализовать все методы, объявленные в интерфейсе
CБыть абстрактным
DИметь конструктор без параметров
Поддержать проект