Это довольно спорная тема, и прежде чем вы скажете "нет", действительно ли это необходимо?
Я программировал около 10 лет, и я не могу честно сказать, что могу вспомнить время, когда наследование решает проблему, которая не может быть решена по-другому. С другой стороны, я могу много раз вспоминать, когда я использовал наследование, потому что чувствовал, что должен, или потому, что, хотя я был умным и в итоге заплатил за него.
Я не могу видеть каких-либо обстоятельств, когда с точки зрения реализации нельзя было использовать агрегацию или другую технику вместо наследования.
Мое единственное предостережение в этом заключается в том, что мы все же разрешаем наследование интерфейсов.
(Обновление)
Давайте дать пример того, зачем ему нужно, а не говорить: "Иногда это просто нужно". Это действительно не полезно вообще. Где ваше доказательство?
(Пример кода обновления 2)
Вот пример классической фигуры, более мощный и более явный ИМО, без наследования. В реальном мире почти никогда не бывает, что что-то действительно "является" чем-то другим. Почти всегда "Выполняется с точки зрения" более точно.
public interface IShape
{
void Draw();
}
public class BasicShape : IShape
{
public void Draw()
{
// All shapes in this system have a dot in the middle except squares.
DrawDotInMiddle();
}
}
public class Circle : IShape
{
private BasicShape _basicShape;
public void Draw()
{
// Draw the circle part
DrawCircle();
_basicShape.Draw();
}
}
public class Square : IShape
{
private BasicShape _basicShape;
public void Draw()
{
// Draw the circle part
DrawSquare();
}
}