Применяли ли вы наследование в своих проектах?

«Применяли ли вы наследование в своих проектах?» — вопрос из категории ООП, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, применял, но с осторожностью, предпочитая композицию там, где это уместно. Классический пример использования — создание иерархии исключений или абстрактных классов с общим поведением.

Пример из проекта на C#: У нас была система обработки документов с базовым абстрактным классом DocumentProcessor.

public abstract class DocumentProcessor
{
    public abstract string DocumentType { get; }
    // Общий шаблонный метод
    public ProcessingResult Process(byte[] data)
    {
        Validate(data);
        var parsedData = Parse(data);
        return Save(parsedData);
    }
    protected abstract void Validate(byte[] data);
    protected abstract DocumentData Parse(byte[] data);
    protected abstract ProcessingResult Save(DocumentData data);
}

public class InvoiceProcessor : DocumentProcessor
{
    public override string DocumentType => "Invoice";
    protected override void Validate(byte[] data) { /* специфичная для инвойса валидация */ }
    protected override DocumentData Parse(byte[] data) { /* парсинг XML инвойса */ }
    protected override ProcessingResult Save(DocumentData data) { /* сохранение в БД */ }
}
// Использование
DocumentProcessor processor = new InvoiceProcessor();
var result = processor.Process(fileBytes);

Почему не всегда наследование: В другом модуле, где сущности User, Admin, Moderator имели разные наборы прав, мы использовали композицию через паттерн «Роли» (Role Pattern), чтобы избежать взрывного роста глубины наследования (проблема «Бриллиантового наследования») и сделать систему гибче для добавления новых прав.