Переопределение методов в 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");
}
}
