Путаница в том, когда использовать частные или защищенные поля

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

public class Car {
    private String modelName;
    private int yearReleased;

//getters and setters

}

Если класс Car расширяется классом ToyotaCar

public class ToyotaCar extends Car{
   // Toyota specific stuff
}

Я хочу, чтобы мой объект ToyotaCar имел поля modelName и yearReleased. И именно поэтому я решил расшириться от Авто класса. Но частные члены не наследуются подклассом (хотя я мог получить доступ к этим полям, используя общедоступный геттер и сеттер). Теперь я запутался в том, должен ли я сделать поля в классе Car защищенными, а не частными. Но люди говорят, что это создает проблемы.

Означает ли это, что независимо от того, какой класс вы пишете, всегда делайте поля закрытыми?

Если да, то в каких случаях используется защищенное ключевое слово? это только для методов, которые мы планируем использовать в наших подклассах?


person DesirePRG    schedule 11.04.2015    source источник
comment
Используйте геттеры. Никто не должен ковыряться во внутренностях класса. Что, если позже вы решите добавить валидацию в сеттеры? protected доступ полностью обходит это. Эмпирическое правило заключается в том, чтобы инкапсулировать все, классы должны иметь методы, а не переменные.   -  person Boris the Spider    schedule 11.04.2015
comment
Экземпляры ToyotaCar делают имеют поля modelName и yearName, хотя к ним по-прежнему нельзя получить доступ методами вне Car.   -  person user253751    schedule 11.04.2015
comment
Бессмысленно говорить, что поля наследуются или не наследуются; это слово на самом деле не имеет строгого определения.   -  person user253751    schedule 11.04.2015


Ответы (3)


Вы сами придумали: хорошая практика — сделать все «приватным» по умолчанию. Затем ваш конкретный дизайн может потребовать, например, возможности использования некоторых атрибутов или (предпочтительно) некоторых методов внутри подкласса. В этой ситуации вам нужно переместить их в положение «защищено» — но только в этой ситуации.

Помните, что использование методов доступа (геттеров и сеттеров) совершенно нормально и может быть выполнено без нарушения инкапсуляции.

person Martin    schedule 11.04.2015

Если существует строгая срочность (из-за определенного дизайна/шаблона) изменения полей из подкласса, вам следует объявить поля своего класса как protected.

Если это не так, то обычно лучший подход состоит в том, чтобы выполнить то же самое, используя общедоступный/защищенный метод-член в родительском классе, обновив эти частные поля в родительском классе, а затем вызвав этот общедоступный/защищенный метод-член из вашего дочернего класса. ' объект.

Таким образом, вы можете добиться реализации, вызвав метод члена родительского класса из объекта дочернего класса, чтобы обновить частные поля этого родительского класса.

person Am_I_Helpful    schedule 11.04.2015

Ключевое слово Protected для объявления переменных используется, чтобы сделать эти переменные экземпляра видимыми для всех других классов в том же пакете, а также для класса [подкласса], который будет расширять суперкласс, включающий эти защищенные переменные.

конечно, вы можете объявить переменные с закрытыми или защищенными модификаторами. Но когда вы объявляете переменную как частную, вы можете скрыть переменную, чтобы другие классы не могли получить к ней прямой доступ, и, с другой стороны, если вы объявите переменную с защищенным вы делаете переменную для прямого доступа к ней без использования каких-либо методов получения, что противоречит принципу ООП.

Итак, по моему мнению, поскольку Car является суперклассом всех других классов, таких как ToyotaCar и т. Д. Объявите переменные в вашем суперклассе как частные, а в подклассе используйте методы getter и setters для чтения и записи в зависимости от ваших потребностей. . Тем самым вы придерживаетесь принципов ООП.

Надеюсь это поможет.

Спасибо

person VSK    schedule 11.04.2015
comment
но мы можем получить доступ к защищенным полям классов из других пакетов, если мы расширяем этот суперкласс? не так ли? - person DesirePRG; 11.04.2015
comment
@DesirePRG, это означает, что вы говорите, что следующее утверждение неверно. Модификаторы защищенного доступа — видны пакету и всем подклассам. Не могли бы вы сказать мне правильное утверждение в отношении защищенных модификаторов. - person VSK; 11.04.2015
comment
@DesirePRG, вы можете получить доступ к защищенным полям других пакетов, если вам нужно расширить этот класс. - person VSK; 11.04.2015
comment
вы не можете получить доступ к защищенным полям других классов только потому, что класс находится в том же пакете. он должен расширить тот класс, который имеет защищенное поле. то, что вы сказали, отличается от того, что я говорю - person DesirePRG; 11.04.2015
comment
@DesirePRG, вы не можете получить доступ к защищенным полям других классов, которые находятся в том же пакете. Заявление, которое вы упомянули, неверно. Доступ к защищенным полям: - person VSK; 11.04.2015
comment
@DesirePRG, вы не можете получить доступ к защищенным полям других классов, которые находятся в том же пакете. Заявление, которое вы упомянули, неверно. Правила доступа к защищенным полям класса: если класс имеет защищенные поля в том же пакете --- вы можете получить к нему доступ, просто создав объект этого класса и не требуя расширения класса, потому что этот класс находится в том же пакете. . Если класс имеет защищенные поля в другом пакете -- вы можете получить к нему доступ в каком-либо другом классе, расширив класс или создав объект этого класса. - person VSK; 11.04.2015