Название очень ясно - переопределенный метод должен соответствовать виртуальному методу, который он переопределяет, не только по своей подписи (имени и параметрам), но также по модификаторам доступа и типу возвращаемого значения.
Зачем? из-за (как минимум) полиморфизма и правил перегрузки методов.
Полиморфизм, который является базовым принципом объектно-ориентированного программирования, - это, по сути, способность смотреть на производный класс, как если бы он был его базовым классом. Это означает, что если у базового класса есть метод, подобный public void move()
, у производного класса также есть этот метод - либо унаследованный без изменений, либо переопределенный в производном классе.
Правило перегрузки методов очень простое - у вас может быть несколько методов с одним и тем же именем, но с другой сигнатурой. Сигнатура метода представляет собой комбинацию его имени и его аргументов, поэтому перегрузки, отличающиеся только типом возвращаемого значения или модификаторами доступа, недопустимы.
Представьте себе , если компилятор позволит вам изменить модификатор доступа в наследовании - вы получите такой класс:
ВНИМАНИЕ: впереди неверный код!
public class Transport
{
public virtual void Move() { Console.WriteLine("trans Moves"); }
}
public class AutoToTravelAdapter : Transport
{
private Auto auto = new Auto();
private override void Move()
{
auto.Drive();
}
}
Таким образом, AutoToTravelAdapter
фактически будет иметь два Move
метода с одинаковой подписью - один закрытый, объявленный в классе AutoToTravelAdapter
, и один открытый, унаследованный от Transport
.
Очевидно, это сделало бы невозможным вызов метода Move()
из класса AutoToTravelAdapter
, поскольку компилятор не мог бы различить эти два метода.