Ответ 1
Почему я могу абстрактно переопределить абстрактный метод?
Для начала, нет никаких практических причин для предотвращения этого. Если это приведет к ошибке компилятора, все, что нужно сделать, это сделать класс более хрупким. Например:
abstract class Foo
{
virtual void DoSomeStuff()
{
//Do Some Stuff
}
}
abstract class Bar : Foo
{
abstract override void DoSomeStuff();
}
Если абстрактное переопределение абстрактного было недопустимым, изменение DoSomeStuff для Foo на абстрактное теперь предотвратит компиляцию Bar. Абстрактное переопределение является избыточным, но не имеет потенциальных отрицательных побочных эффектов, поэтому компилятор в порядке с этим.
Почему нет предупреждения компилятора о том, что то, что я написал, ничего не делает?
Компилятор выдает предупреждения для определенных вещей, представляющих риск: неявное скрытие метода, недоступный код, использование устаревших методов и т.д. Единственная "проблема", которую может указывать ненужное абстрактное переопределение, заключается в том, что код был написан неэффективно. Это не то, о чем заботится компилятор.
Is there some use case where abstract override on an abstract does something useful?
Есть ли какой-то вариант использования, когда абстрактное переопределение абстрактного делает что-то полезное? Не функционально. Однако есть несколько случаев, когда вы можете сделать это намеренно:
- Для улучшения "читабельности" кода. Наличие избыточного абстрактного переопределения послужит напоминанием о том, что метод абстрактный.
- Если в будущие изменения базового класса будет включена виртуальная реализация, вы можете предотвратить доступ некоторых классов к этому базовому классу.
- Если абстрактное переопределение является избыточным, поскольку базовый класс был изменен с виртуальной реализации на абстрактное, его можно смело оставлять в покое.