Я хотел бы представить вам несколько аргументов, защищающих «защищенные» поля в Java:
«Вы можете предпочесть доступ к членам базового класса, используя защищенные поля, по сравнению с общедоступными средствами доступа в ситуации, когда вам необходимо избежать проверки значений».
Однако, если это не так, то следует использовать закрытые поля с общедоступными средствами доступа, чтобы дополнить герметизацию.
Принцип методов получения и установки состоит в том, чтобы обеспечить проверку значений, введенных и выведенных для члена класса. Однако в языках ООП мы оперируем объектами, а не классами. Базовый класс и специализированный класс представляют собой один объект, поэтому совершенно нормально получить доступ к определенным членам класса через защищенное поле.
Рассмотрим следующий абстрактный пример с автомобилем:
- у вас есть базовый класс автомобиль и производный класс Porshe .
- Класс Car может иметь поле типа engine , значение которого не устанавливается в конструкторе Cars (возможно, тип двигателя известен только после инициализации объекта)
- Вы создаете объект класса Porshe , который содержит некоторую логику, используемую для вычисления типа engine с использованием некоторых внешних данных.
В этом примере ожидается, что поле engine имеет публичный геттер, поэтому пользователи автомобиля знают, какой двигатель у машины. Тем не менее, нет никакого публичного сеттера, поскольку мы ожидаем, что водители автомобилей не настроятся на работу с двигателем! Вот почему совершенно нормально сделать engine защищенным полем, чтобы класс Porshe мог установить его значение в будущем.
Да, некоторые люди, вероятно, скажут: «Тогда используйте защищенный установщик!».
И еще раз повторюсь: на языках ООП мы работаем с объектами, а не с классами.
Принцип единой ответственности - да, но как объект, а не как класс.
Если вы скажете: «в какой-то момент, если мы используем защищенные поля с 3 или 5 уровнями наследования, может быть сложно понять, что происходит с полем, если каждый класс выполняет с ним какую-то операцию». И тогда я отвечаю: это еще один антипаттерн - ваш объект, вероятно, слишком велик на данный момент и лишает принципа единственной ответственности.