модификаторы публичного и частного доступа - PullRequest
2 голосов
/ 24 марта 2010

если мы можем получить доступ к приватным членам через сеттеры и геттеры, тогда какой смысл использовать приватные?

Ответы [ 5 ]

3 голосов
/ 24 марта 2010

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

Возьмите следующий пример:

class toto {
  private String someThing;

  public String getSomething();
  public void setSomething(String Something);
}

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

class toto {
  private ComplexSomeThing someThing;

  public String getSomething(){ someThing.toString();}
  public void setSomething(String something){ something = new ComplexSomeThing(something);}
  public ComplexSomeThing (getComplexSomething();
  public void setComplexSomething(ComplexSomething someThing);
}

Есть и другие причины, которые делают инкапсуляцию хорошей вещью (tm), это просто глупый пример, чтобы проиллюстрировать это.


EDIT В настоящее время ведутся споры относительно использования защищенных и закрытых или использования концепций, похожих на свойства в некоторых языках (Delphi, C #), а не на методы получения и установки (как в Java). Защищенный, а не частный, позволяет клиентам вносить более простые изменения, но он больше раскрывает внутреннюю часть вашей системы, поэтому необходимо соблюдать баланс между удобством использования API и его ремонтопригодностью. Однако основной принцип инкапсуляции остается. Независимо от того, какой вариант выбран, нужно по-прежнему демонстрировать функциональность, которая является последовательной и на том же уровне абстракции, и скрывать мрачные детали того, как это делается.

Для меня спор не в том, чтобы объявить джихад против частного, а в том, чтобы найти способ обеспечить расширяемость и гибкость, не нарушая согласованность API.

Здесь некоторые интересные чтения о частном, если вы хотите копать дальше. Однако я должен подчеркнуть, что прежде чем составить мнение о частной жизни, вы должны действительно овладеть понятиями инкапсуляция и полиморфизм , их кажущаяся простота скрывает некоторые тонкие сложности .

1 голос
/ 24 марта 2010

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

1 голос
/ 24 марта 2010

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

То, что ваш метод получения / установки называется getName(), а ваше свойство называется name, не означает, что так будет всегда.

Что если вы хотите изменить переменную на fullName. Если бы вы напрямую обращались к общедоступным переменным, изменение повредило бы много кода. Вместо этого вы можете просто переназначить, откуда getName() получает свои данные.

Один из моих лучших примеров этого - мой собственный класс URL, где я разрешаю создавать и манипулировать URL. Если вы хотите установить схему, вы можете получить $obj->setScheme(). Однако вы не знаете, вручную ли я создаю строку каждый раз, когда вы меняете URL, храню ли я их как отдельные части. Это дает мне гибкость, поскольку я могу хранить ваши данные так, как я хочу.

Кроме того, я могу предварительно обработать данные перед их сохранением. В моем классе URL я предполагаю, что все схемы и имена хостов строчные. Я могу стандартизировать это, преобразовав все строки, сохраненные с помощью setHost(), в строчные буквы, а затем сохранив их. Если бы я использовал открытую переменную, вы должны были бы предположить, что клиент, который поместил данные, правильно их сохранял.

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

0 голосов
/ 24 марта 2010

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

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

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

0 голосов
/ 24 марта 2010

Я думаю, вы действительно хотите понять, почему мы используем открытые свойства с закрытыми полями поддержки, а не просто с открытыми полями. Есть несколько вопросов о SO, как это; вот один:

В чем разница между полем и свойством в C #?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...