Можно ли изменить поведение метода в классе-наследнике?

«Можно ли изменить поведение метода в классе-наследнике?» — вопрос из категории ООП, который задают на 25% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, поведение метода можно изменить в производном классе, но механизм и семантика зависят от используемого подхода: полиморфное переопределение или скрытие метода.

1. Полиморфное переопределение (override): Используется, когда метод базового класса помечен как virtual или abstract. Это основа полиморфизма.

class Logger {
    public virtual void Log(string message) {
        Console.WriteLine($"[INFO] {message}"); // Базовая реализация
    }
}

class FileLogger : Logger {
    public override void Log(string message) {
        // Полностью новая реализация для файлового вывода
        File.AppendAllText("log.txt", $"{DateTime.Now}: {message}n");
    }
}

// Использование полиморфизма
Logger logger = new FileLogger();
logger.Log("Test"); // Вызовется FileLogger.Log

2. Скрытие метода (new): Применяется, если метод базового класса не virtual. Создаётся новый, независимый метод с тем же именем.

class Base {
    public void Display() => Console.WriteLine("Base.Display");
}

class Derived : Base {
    public new void Display() => Console.WriteLine("Derived.Display");
}

// Поведение зависит от типа ссылки
Base obj1 = new Derived();
obj1.Display(); // Вывод: "Base.Display" (вызван метод из Base)

Derived obj2 = new Derived();
obj2.Display(); // Вывод: "Derived.Display" (вызван метод из Derived)

Практические рекомендации:

  • Используйте override для реализации полиморфного поведения, когда разные типы объектов должны по-разному реагировать на один и тот же вызов метода.
  • Ключевое слово new следует применять осознанно, обычно при расширении сторонних классов, где вы не можете изменить базовый код. Это может привести к путанице, так как поведение зависит от типа переменной, а не от реального объекта.