ООП, защищенный против общественности.Когда использовать? - PullRequest
2 голосов
/ 15 сентября 2010

Я пытаюсь понять преимущества того, что переменная класса должна быть закрытой по сравнению с общедоступной.Я понимаю, что получатели / установщики получают доступ / изменяют личные / защищенные данные, но единственная ли его цель - «не дать мне испортить мои данные»?Пример: я не понимаю, как сказать, что

$person->age = x;//bad?

имеет другой потенциал для разрушения, чем

$person->set_x(x);//reccommended in OOP articles

Ответы [ 5 ]

13 голосов
/ 15 сентября 2010

Все дело в инкапсуляции.

Скажем, вы используете $person->age = x. На данный момент, это будет работать нормально, и скажем, у вас есть эта линия в 100 местах. Позже выясняется, что вы хотите ограничить age, скажем, числами больше 0. С прямым доступом к переменной-члену нет никакого способа легко применить это ограничение.

Но допустим, вы изначально написали $person->set_age(x) в этих 100 местах. Теперь вы можете изменить свой сеттер с

private $_age;
public void age($new_age) {
    $this->_age = $new_age;
}

до

private $_age;
public void age($new_age) {
    if ($new_age > 0) {
        $this->_age = $new_age;
    }
}

Вам не нужно трогать ни одного потребителя метода set_age; изменения "просто работают". В этом вся прелесть ООП: за одним вызовом метода можно скрыть множество деталей реализации.

Инкапсуляция может помочь и в другом месте: скажем, вы хотели иметь подкласс Person, который регистрировал каждое изменение возраста. С помощью метода установки это так же просто, как переопределение; с прямым доступом к переменной, это будет беспорядок.

4 голосов
/ 15 сентября 2010

Предоставляя методы доступа (методы установки / получения или использование свойств в языках, которые их поддерживают, например C #), разработчик может определить более стабильный контракт между классом и его пользователями. Вместо прямого доступа к полю, фактически читая или записывая область памяти, пользователь вынужден вызывать метод, который, в свою очередь, может инкапсулировать любую необходимую логику.

В свою очередь, при изменении внутреннего дизайна класса его контракт нужно менять реже. Следовательно, удобство сопровождения и стабильность кода улучшены.

Обратите внимание, что производительность не является проблемой, поскольку современные JIT-компиляторы способны оптимизировать вызовы тривиальных методов получения / установки таким образом, что фактический вызов исключается, а код эквивалентен прямому доступу к базовой области памяти.

Edit:

Кроме того, сеттер и геттер обычно могут иметь различную видимость (публичную / защищенную / приватную), обеспечивая дополнительное преимущество более детального управления операциями чтения / записи над указанным значением.

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

0 голосов
/ 19 ноября 2018

Защищенное ключевое слово часто неправильно понимают и, возможно, злоупотребляют.Короче говоря, защищенные участники предназначены для связи с подклассами, а открытые - для связи с вызывающими.

0 голосов
/ 15 сентября 2010

Ну, я думаю, что метод set / get может помочь лучше гарантировать атрибуты, так как если вы напрямую измените значение, это может вызвать некоторые проблемы, например, вредные для кода.Я думаю, что set / get предоставляет метод для вызова пользователем, а не для непосредственного обращения к атрибутам.

0 голосов
/ 15 сентября 2010

Не позволяйте вам калечить это, не позволяйте другим калечить это, и выражайте идею, что непубличные участники не являются частью того, что другие должны видеть - таким образом достигается Инкапсуляция .

...