Переопределение методов в C#
Наследование — одна из основных концепций объектно-ориентированного программирования. Она говорит о том, что поведение класса-предка может быть переопределено в классе-потомке.
Рассмотрим на примере
public class A { public virtual void DoWork() { Console.WriteLine("class A"); } } public class B : A { public override void DoWork() { Console.WriteLine("class B"); } }
Здесь есть 2 класса: A — предок, B — потомок. В классе A объявлен метод
public virtual void DoWork()
ключевое слово virtual как раз и говорит о том, что этот метод может быть переопределен в потомке.
В классе B этот метод переопределен с помощью ключевого слова override.
работает это так:
var a = new A(); var b = new B(); a.DoWork(); // class A b.DoWork(); // class B (b as A).DoWork(); // class B
т.е. не зависимо от того, какого типа переменная, метод будет браться из реального класса.
Перекрытие методов в C#
Изменим класс B следующим образом:
public class B : A { public void DoWork() { Console.WriteLine("class B"); } }
Отличие в том, что отсутствует ключевое слово override. В этом случае метод предка не переопределен, а перекрыт. В этой ситуации наличие или отсутствие ключевого слова virtual в классе A не имеет значения.
Поведение такого класса будет отличаться:
var a = new A(); var b = new B(); a.DoWork(); // class A b.DoWork(); // class B (b as A).DoWork(); // class A
как мы видим, метод берется не из реального класса переменной, а от типа, к которому переменная переопределена. Это неочевидное поведение может быть причиной трудно находимых багов и делать так крайне не рекомендуется. Среда разработки подсветит перекрывающий метод как warning.
Если вам нужно именно такое поведение, нужно помечать перекрывающий метод ключевым словом new
public class B : A { public new void DoWork() { Console.WriteLine("class B"); } }