Что такое абстрактный класс в C# и чем он отличается от интерфейса?
Нужно сделать базовый класс с «пустыми» методами, которые потомки обязаны реализовать. Нашёл слово abstract. Что такое абстрактный класс и когда брать его, а когда интерфейс?
abstract class Shape
{
public abstract double Area();
}
2 ответа
Абстрактный класс — это незавершённый базовый класс: его нельзя создать через new, он существует только чтобы от него наследовались. В нём могут быть абстрактные методы (без тела — «чистые», их обязан реализовать потомок) и обычные методы с готовым кодом.
abstract class Shape
{
public string Name = "фигура";
public abstract double Area(); // без тела — потомок ОБЯЗАН реализовать
public void Describe() // обычный метод с реализацией
=> Console.WriteLine($"{Name}: площадь {Area():F2}");
}
class Circle : Shape
{
public double R;
public override double Area() => Math.PI * R * R;
}
// var s = new Shape(); // ОШИБКА: нельзя создать абстрактный класс
var c = new Circle { R = 2 };
c.Describe(); // фигура: площадь 12.57
Абстрактный класс vs интерфейс:
| abstract class | interface | |
|---|---|---|
| Поля/состояние | да | нет (только свойства) |
| Готовая реализация методов | да | частично (с C# 8) |
| Конструкторы | да | нет |
| Сколько можно унаследовать | один | сколько угодно |
Правило выбора: берите абстрактный класс, когда у типов есть общее состояние и общий код (как Describe выше) и отношение «является». Берите интерфейс, когда нужно описать только контракт-способность («умеет сравниваться», «можно сериализовать») и/или нужно несколько таких контрактов на одном классе.
Маленькое уточнение по терминам из вопроса: «класс с чистыми методами» (pure virtual в C++) — в C# это и есть abstract-методы. У них нет тела, только сигнатура и точка с запятой:
public abstract void Draw(); // нет { }, есть ;
Если в классе есть хоть один abstract-метод, сам класс тоже обязан быть abstract. И каждый абстрактный метод потомок реализует через override.