← Назад к вопросам

Останется ли класс иммутабельным после наследования от другого класса

2.0 Middle🔥 91 комментариев
#ООП

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Наследование и иммутабельность в Java

Ответ на этот вопрос зависит от того, от какого класса происходит наследование. Это критически важный момент при проектировании иммутабельных классов.

Наследование от иммутабельного класса

Если базовый класс является полностью иммутабельным, то наследующий класс останется иммутабельным при соблюдении правил:

final class ImmutableParent {
    private final int value;
    
    public ImmutableParent(int value) {
        this.value = value;
    }
    
    public int getValue() {
        return value;
    }
}

final class ImmutableChild extends ImmutableParent {
    private final String name;
    
    public ImmutableChild(int value, String name) {
        super(value);
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
}

Наследование от мутабельного класса

Если базовый класс содержит мутабельные поля, то наследник также станет мутабельным:

class MutableParent {
    private List<String> items = new ArrayList<>();
    
    public void addItem(String item) {
        items.add(item);
    }
}

final class ChildOfMutable extends MutableParent {
    private final int id;
}

Основные правила для иммутабельности

1. Базовый класс должен быть иммутабельным

  • Все поля должны быть final
  • Нет setter-методов
  • Нет методов, изменяющих состояние

2. Наследник должен быть final

final class ImprovedChild extends ImmutableParent { }

Без модификатора final кто-то может создать подкласс и добавить мутабельные поля.

3. Защита от утечек mutable ссылок

final class SafeChild extends ImmutableParent {
    private final List<String> items;
    
    public SafeChild(int value, List<String> items) {
        super(value);
        this.items = new ArrayList<>(items);
    }
    
    public List<String> getItems() {
        return Collections.unmodifiableList(items);
    }
}

Классический пример: String vs Date

String - иммутабелен и final, невозможно переопределить. Date - мутабелен, попытка создать иммутабельный наследник будет хрупкой.

Современный подход: композиция вместо наследования

Для гарантированной иммутабельности лучше использовать композицию:

final class ImmutableWrapper {
    private final Date date;
    
    public ImmutableWrapper(Date date) {
        this.date = new Date(date.getTime());
    }
    
    public Date getDate() {
        return new Date(date.getTime());
    }
}

Заключение

Класс останется иммутабельным после наследования только если:

  1. Базовый класс полностью иммутабелен
  2. Наследник помечен как final
  3. Все новые поля имеют тип final
  4. Нет методов, изменяющих состояние

Это одна из причин, почему иммутабельные классы Java помечены как final.

Останется ли класс иммутабельным после наследования от другого класса | PrepBro