что такое private public protected
Модификаторы доступа (Руководство по программированию в C#)
Все типы и члены типов имеют уровень доступности. Он определяет возможность их использования из другого кода в вашей или в других сборках. Следующие модификаторы доступа позволяют указать доступность типа или члена при объявлении:
Сводная таблица
Расположение вызывающего объекта | public | protected internal | protected | internal | private protected | private |
---|---|---|---|---|---|---|
В классе | ✔️️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
Производный класс (та же сборка) | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ❌ |
Непроизводный класс (та же сборка) | ✔️ | ✔️ | ❌ | ✔️ | ❌ | ❌ |
Производный класс (другая сборка) | ✔️ | ✔️ | ✔️ | ❌ | ❌ | ❌ |
Непроизводный класс (другая сборка) | ✔️ | ❌ | ❌ | ❌ | ❌ | ❌ |
В следующих примерах показано, как изменить модификаторы доступа для типа или члена типа:
Не все модификаторы доступа подходят для всех типов или членов во всех контекстах. В некоторых случаях доступность члена типа ограничивается доступностью содержащего его типа.
Доступность классов, записей и структур
Доступность членов классов, записей и структур
Как правило, уровень доступности члена не может быть выше уровня доступности типа, в который он входит. При этом член public внутреннего класса может быть доступен за пределами сборки, если он реализует методы интерфейса или переопределяет виртуальные методы, определенные в открытом базовом классе.
Методы завершения не могут иметь модификаторы доступа.
Другие типы
Спецификация языка C#
Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.
В чем разница между public, protected и private доступом?
Примеры:
public function doSomething() <
private function doSomething() <
protected function doSomething() <
Ответ 1
public область видимости используется, чтобы сделать это свойство/метод доступным из любого места, других классов и экземпляров объекта.
private область видимости, если необходимо, чтобы ваше свойство/метод было видно только в его собственном классе.
Если вы не используете модификатор видимости, свойство/метод будут общедоступными.
Ответ 2
Public:
Тот же класс, который его объявил.
Классы, наследующие объявленный выше класс.
Любые внешние элементы вне этого класса также могут получить доступ к ним.
Пример:
class Daddy extends GrandPa <
// Public переменная, которая доступна также из внешнего класса!
$outsiderWantstoKnowGrandpasName = new GrandPa;
Protected:
Тот же класс, который его объявил.
Классы, наследующие объявленный выше класс.
Внешние члены не могут получить доступ к этим переменным. «Внешние» в том смысле, что они не являются экземплярами объекта самого объявленного класса.
Пример:
class Daddy extends GrandPa <
$outsiderWantstoKnowGrandpasName = new GrandPa;
Точная ошибка будет такой:
Private:
Тот же класс, который его объявил.
Внешние члены не могут получить доступ к этим переменным. «Внешние» в том смысле, что они не являются экземплярами объекта самого объявленного класса и даже не являются классами, наследующими объявленный класс.
Пример:
class Daddy extends GrandPa<
$outsiderWantstoKnowGrandpasName = new GrandPa;
Сообщения об ошибках будут следующими:
Примечание: Неопределенное свойство: Daddy::$name
Неустранимая ошибка: невозможно получить доступ к частному свойству GrandPa::$name
Ответ 3
Обычно хорошей практикой считается установка по умолчанию минимальной требуемой видимости, поскольку это способствует инкапсуляции данных и хорошему дизайну интерфейса. При рассмотрении переменной-члена и видимости метода подумайте о роли, которую член играет во взаимодействии с другими объектами.
Если вы «кодируете интерфейс, а не реализацию», то обычно довольно просто принимать решения о видимости. В общем, переменные должны быть закрытыми или защищенными, если у вас нет веских причин для их раскрытия. Вместо этого используйте общедоступные методы доступа (геттеры/сеттеры) для ограничения и регулирования доступа к внутренним компонентам класса.
Водитель не знает и не должен заботиться о том, как эти действия реализуются внутренними компонентами автомобиля, и раскрытие этой функции может быть опасно для водителя и других людей на дороге. Следовательно, хорошая практика разработки общедоступного интерфейса и инкапсуляции данных за этим интерфейсом.
Мы будем очень благодарны
если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.
Методы доступа. Наиболее популярные ситуации
Статья в первую очередь расчитана на начинающих разработчиков, либо для тех, кто только начинает переходить от процедурного стиля программирования к ООП, посему матерых гуру просьба не вгонять в минуса 🙂
Права доступа к свойствам и методам — это на первый взгляд всего лишь три слова: private, protected и public. Но что скрывается за ними? Какие преимущества это дает в разработке? И как их правильно использовать? Здесь, как и во всех других аспектах программирования, без практики не разобраться…
Одна из трех основных концепций ООП — наследование (другие две: инкапсуляция и полиморфизм). Вобщем-то именно для нее и были реализованы права доступов. Основанная идея наследования: Дочерний объект, при наследовании (extend) родителя перенимает себе все родительские методы и свойства, а так же может обзавестись своими собственными. Понимая эту базу, можно перейти в всему что находится ниже…
Private — объявляет метод или свойство доступным только в том классе в котором он присутствует. Тоесть к private методам и свойствам мы не можем обращаться ни из объектов, ни из дочерних классов.
Protected — объявляет метод или свойство защищенными. Тоесть такими, которые не могут быть доступны из объекта, реализующего класс, но вполне может быть использовано в дочерних классах.
Public — публичный. Классы и методы, объявленные public, могут быть доступны как внутри самого класса, так и в дочерних классах и в объектах, реализовавших класс.
Сразу хочу заметить, что при наследовании, методы доступа изменяться могут только к более лояльным. тоесть в следующей последовательности, но не обратно: private → protected → public
Так же методы могут быть final тоесть такими, которые невозможно переопределить в классах потомках.
Вобщем-то все методы доступа используются исключительно для самодокументации кода и не несут никакой логической составляющей, так что и без них жизнь только тяжела, но не невозможна, что доказывает РНР4, в котором все методы и свойства были публичными…
Практика
Похожим способом ведут себя и сеттеры (setter\’s), когда нам необходимо иметь возможность установить значение переменной, но не читать ее напрямую, так как она, к примеру, должна быть преобразована прежде чем быть использованной. Пример метода сеттера:
Еще одним вариантом реализации доступа к методам, когда метод должен быть отовсюду доступен только для чтения, является введение \«псевдо-свойства\»:
if (empty($value)) <
$value = //. тут значение создается по каким-то известным параметрам и повлиять извне на него мы никак не сможем
>
Хорошей практикой является сокрытие всех свойств методом private и, в зависимости от нужд, создавать для них сеттеры или геттеры, но нужно быть внимательным, что если для свойства существует и сеттер и геттер, а дополнительной логики обработки данных нет, то не проще ли их убрать, а свойство сделать публичным? 🙂
Модификаторы private, protected, public в Java
Модификаторы доступа private, protected, public ставятся перед именем класса, метода или поля и ограничивают доступ к нему. К локальным переменным модификаторы доступа не применимы.
Помимо этих трех явных модификаторов, есть еще так называемый default-модификатор, или модификатор по умолчанию, иначе говоря — это отсутствие всякого модификатора. Но это отсутствие тоже подразумевает свои правила доступа (видимость только внутри пакета).
Зачем нужны модификаторы доступа
Модификаторы доступа существуют для того, чтобы сделать код надежнее и защищеннее. Нужно максимально ограничивать видимость своих классов, методов и полей, и открывать их только там, где это действительно необходимо. Если вы откроете что-то лишнее, то другой разработчик (или даже вы сами) может по ошибке воспользоваться открытым классом/методом. Чем это чревато? А тем, что если в дальнейшем вы исправите свой код (отвечающий за внутреннюю реализацию, но открытый для пользования извне), то код другого программиста перестанет работать, так как опирается на ваш код. Открывать нужно только то, что вы планируете поддерживать и что будет стабильно работать (без изменения контракта) во всех последующих версиях. Все остальное — внутренняя реализация, которая касается только вас и может меняться, ее никто не должен использовать.
Правила доступа
На картинке показаны правила доступа к полю или методу с конкретным модификатором (последний столбец — про модули, они появились в Java 9):
Модификаторы доступа в Java
Модификатор private
Это самый ограничивающий модификатор. К полям и методам, помеченным ключевым словом private, можно обратиться только из того же класса, где они находятся.
Допустим у нас есть класс A с private полем privateVar и с private методом privateMethod(). Из класса A мы можем обращаться к полю, см. обращение this.privateVar:
А теперь попробуем обратиться к этому полю и методу из класса B, код не скомпилируется:
Вышеприведенный код выдает ошибки компиляции:
Иногда возникает вопрос
Может ли объект A получить доступ к private методам и полям другого объекта A?
Да, может. Обратите внимание на функцию main() из вышеприведенного класса A, в которой создается новый объект A и идет обращение к его методам и полям (не через this):
Как показано выше, мы обращаемся в методе main() к private полю privateVar другого объекта A, и это законно. Все потому, что в Java ограничения доступа применимы на уровне класса, а не на уровне объекта (не обязательно, чтоб обращение шло к тому же экземпляру, главное, что он в том же классе).
Можно ли переопределить private метод?
Нельзя, метод в подклассе не будет иметь никакого отношения к методу в суперклассе, так как private метод нигде не виден. Давайте попытаемся унаследоваться от класса A и «переопределить» private метод privateMethod():
Попробуем создать объект SubA и вызвать privateMethod() на A:
Как видите, срабатывает метод privateMethod() класса A, то есть переопределения не происходит:
Это происходит потому, что метод privateMethod() класса SubA не переопределяет метод privateMethod() класса A, а является независимым методом.
Модификатор default
Если мы не ставим никакого модификатора доступа перед методом, полем или классом, то этот метод/поле/класс видимы из кода только внутри пакета, в котором они находятся.
Давайте продемонстрируем это. Создадим снова класс A в пакете .def:
И создадим в этом же пакете класс B, из которого будем пытаться получить доступ к полям и методам A, как и раньше:
В этот раз код компилируется, все в порядке — доступ есть.
Если бы класс B находится в другом пакете (отличном от ru.sysout.accessmodifiers.def, в том числе в подпакете), то доступа бы не было.
Модификатор protected
Следующий по строгости — модификатор protected. Он также разрешает доступ к помеченным с помощью него полям и методам из кода внутри того же пакета. Но помимо этого, он дает поблажки подклассам, находящимся в другом пакете. Подкласс может обращаться к protected полям и методам суперкласса, даже если подкласс находится в другом пакете.
Снова создадим класс A с protected полем и методом:
Создадим в другом пакете класс C — наследника класса A и попытаемся получить доступ к полям методам класса A из класса C:
Как показано выше, обращение к полю и методу через this работает из другого пакета.
Также работает обращение ко всем другим экземплярам типа C, но к другим экземплярам типа A обращение не работает.
Модификатор public
Тут все просто — к полю и методу с модификатором public имеет доступ любой код. Давайте еще раз перепишем класс A:
И обратимся к его полю и методу из класса B, который находится в другом пакете и никакого отношения к классу A не имеет:
Все получилось, обращение работает.
Какой модификатор выбрать?
Правило выбора модификатора такое — надо по возможности выбирать:
То есть надо максимально ограничивать видимость члена класса. Сначала надо попробовать сделать все private, и при необходимости открывать видимость.
Мы рассмотрели тонкости использования модификаторов доступа. Код примеров можно посмотреть на GitHub.
Уровни доступности (Справочник по C#)
Объявленная доступность | Значение |
---|---|
public | Неограниченный доступ. |
protected | Доступ ограничен содержащим классом или типами, которые являются производными от содержащего класса. |
internal | Доступ ограничен текущей сборкой. |
protected internal | Доступ ограничен текущей сборкой или типами, которые являются производными от содержащего класса. |
private | Доступ ограничен содержащим типом. |
private protected | Доступ ограничен содержащим классом или типами, которые являются производными от содержащего класса в текущей сборке. Доступно с версии C# 7.2. |
Модификаторы доступа не могут быть указаны для пространств имен. Пространства имен не имеют ограничений доступа.
В зависимости от контекста, в котором производится объявление члена, допускаются только некоторые объявленные уровни доступности. Если модификатор доступа не указывается в объявлении члена, используется доступность по умолчанию.
Вложенные типы, которые являются членами других типов, могут иметь объявленные уровни доступности, как указано в следующей таблице.
Члены типа | Уровень доступности членов по умолчанию | Допустимые объявленные уровни доступности члена |
---|---|---|
enum | public | None |
class | private | public private protected |
interface | public | public private protected |
struct | private | public * Элемент interface с доступностью типа private должен иметь реализацию по умолчанию. Доступность вложенного типа зависит от домена доступности, который определяется объявленным уровнем доступности члена и доменом доступности непосредственно вмещающего его типа. Однако домен доступности вложенного типа не может выходить за границы домена доступности содержащего его типа. Спецификация языка C#Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.
|