Полное руководство по языку программирования С# 14 и платформе .NET 10 / Интерфейсы

Реализация интерфейсов в базовых и производных классах

Начальный ⏱ 4 мин чтения 👁 2 🕓 обновлено 11.08.2026

Если класс применяет интерфейс, то этот класс должен реализовать все методы и свойства интерфейса, которые не имеют реализации по умолчанию. Однако также можно и не реализовать методы, сделав их абстрактными, переложив право их реализации на производные классы:


interface IMovable
{
	void Move();
}
abstract class Person : IMovable
{
	public abstract void Move();
}
class Driver : Person
{
	public override void Move() => Console.WriteLine("Шофер ведет машину");
}

При реализации интерфейса учитываются также методы и свойства, унаследованные от базового класса. Например:


IAction action = new HeroAction();
action.Move();  // Move in BaseAction

interface IAction
{
    void Move();
}
class BaseAction
{
    public void Move() => Console.WriteLine("Move in BaseAction");
}
class HeroAction : BaseAction, IAction{ }

Здесь класс HeroAction реализует интерфейс IAction, однако для реализации метода Move из интерфейса применяется метод Move, унаследованный от базового класса BaseAction. Таким образом, класс HeroAction может не реализовать метод Move, так как этот метод уже определен в базовом классе BaseAction.

Следует отметить, что если класс одновременно наследует другой класс и реализует интерфейс, как в примере выше класс HeroAction, то название базового класса должно быть указано до реализуемых интерфейсов:

class HeroAction : BaseAction, IAction

Изменение реализации интерфейсов в производных классах

Может сложиться ситуация, что базовый класс реализовал интерфейс, но в классе-наследнике необходимо изменить реализацию этого интерфейса. Что в этом случае делать? В этом случае мы можем использовать либо переопределение, либо скрытие метода или свойства интерфейса.

Первый вариант - переопределение виртуальных/абстрактных методов:


interface IAction
{
    void Move();
}
class BaseAction : IAction
{
    public virtual void Move() => Console.WriteLine("Move in BaseAction");
}
class HeroAction : BaseAction
{
    public override void Move() => Console.WriteLine("Move in HeroAction");
}

В базовом классе BaseAction реализованный метод интерфейса определен как виртуальный (можно было бы также сделать его абстрактным), а в производном классе он переопределен.

При вызове метода через переменную интерфейса, если она ссылается на объект производного класса, будет использоваться реализация из производного класса:


BaseAction action1 = new HeroAction();
action1.Move();            // Move in HeroAction

IAction action2 = new HeroAction();
action2.Move();             // Move in HeroAction

Второй вариант - скрытие метода в производном классе:


interface IAction
{
    void Move();
}
class BaseAction : IAction
{
    public void Move() => Console.WriteLine("Move in BaseAction");

}
class HeroAction : BaseAction
{
    public new void Move() => Console.WriteLine("Move in HeroAction");
}

Также используем эти классы:


BaseAction action1 = new HeroAction();
action1.Move();            // Move in BaseAction

IAction action2 = new HeroAction();
action2.Move();           // Move in BaseAction

Так как интерфейс реализован именно в классе BaseAction, то через переменную action2 можно обратиться только к реализации метода Move из базового класса BaseAction.

Третий вариант - повторная реализация интерфейса в классе-наследнике:


interface IAction
{
    void Move();
}
class BaseAction : IAction
{
    public void Move() => Console.WriteLine("Move in BaseAction");
}
class HeroAction : BaseAction, IAction
{
    public new void Move() =>  Console.WriteLine("Move in HeroAction");
}

В этом случае реализации этого метода из базового класса будет игнорироваться:


BaseAction action1 = new HeroAction();
action1.Move();            // Move in BaseAction

IAction action2 = new HeroAction();
action2.Move();             // Move in HeroAction

HeroAction action3 = new HeroAction();
action3.Move();             // Move in HeroAction

Также стоит отметить, что в случае с переменной action1 по-прежнему действует ранее связывание, в силу которого через эту переменную можно вызвать реализацию метода Move только из базового класса, который эта переменная представляет.

Четвертый вариант: явная реализация интерфейса:


interface IAction
{
    void Move();
}
class BaseAction : IAction
{
    public void Move() => Console.WriteLine("Move in BaseAction");
}
class HeroAction : BaseAction, IAction
{
    public new void Move() => Console.WriteLine("Move in HeroAction");
    // явная реализация интерфейса
    void IAction.Move() => Console.WriteLine("Move in IAction");
}

В этом случае для переменной IAction будет использоваться явная реализация интерфейса IAction, а для переменной HeroAction по прежнему будет использоваться неявная реализация:


BaseAction action1 = new HeroAction();
action1.Move();            // Move in BaseAction

IAction action2 = new HeroAction();
action2.Move();             // Move in IAction

HeroAction action3 = new HeroAction();
action3.Move();             // Move in HeroAction

Проверь себя

📋 Тест по теме «Реализация интерфейсов в базовых и производных классах» Тест по теме

Практические задания

Лёгкое Ручная проверка Заполните пропуск в коде (1)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

_____ IMovable
{
	void Move();
}
abstract class Person : IMovable
{
	public abstract void Move();
}
class Driver : Person
{
	public override void Move() => Console.WriteLine("Шофер ведет машину");
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (2)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

IAction _____ = new HeroAction();
action.Move();  // Move in BaseAction

interface IAction
{
    void Move();
}
class BaseAction
{
    public void Move() => Console.WriteLine("Move in BaseAction");
}
class HeroAction : BaseAction, IAction{ }
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (3)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

class HeroAction : BaseAction, _____
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

interface IAction
{
    void Move();
}
class _____ : IAction
{
    public virtual void Move() => Console.WriteLine("Move in BaseAction");
}
class HeroAction : BaseAction
{
    public override void Move() => Console.WriteLine("Move in HeroAction");
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

BaseAction _____ = new HeroAction();
action1.Move();            // Move in HeroAction

IAction action2 = new HeroAction();
action2.Move();             // Move in HeroAction
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (1)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

interface IMovable
{
	void Move();
}
_____ class Person : IMovable
{
	public abstract void Move();
}
class Driver : Person
{
	public _____ void Move() => Console.WriteLine("Шофер ведет машину");
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (2)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

IAction action = _____ HeroAction();
action._____();  // Move in BaseAction

interface IAction
{
    void Move();
}
class BaseAction
{
    public void Move() => Console.WriteLine("Move in BaseAction");
}
class HeroAction : BaseAction, IAction{ }
Войдите, чтобы отправить решение
Среднее Ручная проверка Расставьте строки кода в правильном порядке
+20 XP

Строки кода из примера этого урока перемешаны. Впишите их в правильном порядке, каждую строку — с новой строки.

action1.Move();            // Move in HeroAction
IAction action2 = new HeroAction();
action2.Move();             // Move in HeroAction
BaseAction action1 = new HeroAction();
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «Реализация интерфейсов в базовых и производных классах»
+30 XP

Опишите своими словами, что делает приведённый пример кода из урока «Реализация интерфейсов в базовых и производных классах», и предложите одно осмысленное изменение (например, другое входное значение или дополнительное условие). Приведите итоговый код.

interface IMovable
{
	void Move();
}
abstract class Person : IMovable
{
	public abstract void Move();
}
class Driver : Person
{
	public override void Move() => Console.WriteLine("Шофер ведет машину");
}
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «Реализация интерфейсов в базовых и производных классах»
+30 XP

Изучите приведённый фрагмент кода и опишите, при каких входных данных или условиях он может сработать не так, как ожидается (граничный случай, отсутствие проверки и т.п.). Предложите исправленный вариант.

IAction action = new HeroAction();
action.Move();  // Move in BaseAction

interface IAction
{
    void Move();
}
class BaseAction
{
    public void Move() => Console.WriteLine("Move in BaseAction");
}
class HeroAction : BaseAction, IAction{ }
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «Реализация интерфейсов в базовых и производных классах»
+50 XP

Соберите небольшую программу, которая последовательно демонстрирует ключевые идеи урока. Программа должна быть рабочей и содержать минимум два самостоятельно написанных фрагмента, а не просто копию примера из урока.

Войдите, чтобы отправить решение
Домашнее задание Ручная проверка Домашнее задание по теме «Реализация интерфейсов в базовых и производных классах»
+25 XP

Напишите собственную небольшую программу, применяющую материал темы «Реализация интерфейсов в базовых и производных классах». Используйте не менее одной конструкции, показанной в примерах урока. Прикрепите код решения и краткое описание того, что он делает.

Войдите, чтобы отправить решение

Обсуждение (0)

Войдите, чтобы оставить комментарий.