Переменная видна во всех классах php

В чем разница между публичным, частным и защищенным?

Когда и почему следует использовать public , private и protected функции и переменные внутри класса? В чем разница между ними? Примеры:

// Public public $variable; public function doSomething() < // . >// Private private $variable; private function doSomething() < // . >// Protected protected $variable; protected function doSomething() < // . >

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

16 ответов

  • public область видимости, чтобы сделать эту переменную/функцию доступной из любого места, других классов и экземпляров объекта.
  • private область, когда вы хотите, чтобы ваша переменная/функция была видна только в своем собственном классе.
  • protected область, когда вы хотите сделать вашу переменную/функцию видимой во всех классах, которые расширяют текущий класс, включая родительский класс.

Подробнее: (для полной информации)

protected область, когда вы хотите сделать вашу переменную / функцию видимой во всех классах, которые расширяют текущий класс И его родительские классы .

@Shahid — я не понимаю вашу точку зрения. Любой класс, который расширяет класс A, также расширяет родительский класс A, нет?

@JDelage — Пожалуйста, смотрите ссылку http://www.php.net/manual/en/language.oop5.visibility.php#109324

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

Читайте также:  Python telegram bot api команды

Нет такой вещи как «экземпляр объекта». Существует только «экземпляр класса», который является объектом. Пожалуйста, отредактируйте свой ответ.

Изображение 723

Общественность:

Когда вы объявляете метод (функцию) или свойство (переменную) как public , к этим методам и свойствам можно получить доступ:

  • Тот же класс, который объявил это.
  • Классы, которые наследуют объявленный выше класс.
  • Любые посторонние элементы вне этого класса также могут получить доступ к этим вещам.
 class Daddy extends GrandPa // Inherited class < function displayGrandPaName() < return $this->name; // The public variable will be available to the inherited class > > // Inherited class Daddy wants to know Grandpas Name $daddy = new Daddy; echo $daddy->displayGrandPaName(); // Prints 'Mark Henry' // Public variables can also be accessed outside of the class! $outsiderWantstoKnowGrandpasName = new GrandPa; echo $outsiderWantstoKnowGrandpasName->name; // Prints 'Mark Henry' 

Защищено:

Когда вы объявляете метод (функцию) или свойство (переменную) как protected , эти методы и свойства могут быть доступны

Члены посторонних не могут получить доступ к этим переменным. «Посторонние» в том смысле, что они не являются объектными экземплярами самого объявленного класса.

 class Daddy extends GrandPa < function displayGrandPaName() < return $this->name; > > $daddy = new Daddy; echo $daddy->displayGrandPaName(); // Prints 'Mark Henry' $outsiderWantstoKnowGrandpasName = new GrandPa; echo $outsiderWantstoKnowGrandpasName->name; // Results in a Fatal Error 

Точная ошибка будет такой:

Неустранимая ошибка PHP: невозможно получить доступ к защищенному свойству GrandPa :: $ name

Частный:

Когда вы объявляете метод (функцию) или свойство (переменную) как private , к этим методам и свойствам можно получить доступ:

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

 class Daddy extends GrandPa < function displayGrandPaName() < return $this->name; > > $daddy = new Daddy; echo $daddy->displayGrandPaName(); // Results in a Notice $outsiderWantstoKnowGrandpasName = new GrandPa; echo $outsiderWantstoKnowGrandpasName->name; // Results in a Fatal Error 

Точные сообщения об ошибках будут:

Примечание: неопределенное свойство: папа :: $ name
Неустранимая ошибка: невозможно получить доступ к частной собственности GrandPa :: $ name

Рассекая Дедушку с помощью отражения

Эта тема на самом деле не выходит за рамки, и я добавляю ее сюда, чтобы доказать, что рефлексия действительно мощная. Как я уже говорил в трех приведенных выше примерах, protected и private члены (свойства и методы) не могут быть доступны за пределами класса.

Тем не менее, с отражением вы можете сделать экстраординарное, даже имея доступ к protected и private членам вне класса!

Ну что такое отражение?

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

преамбула

У нас есть класс с именем Grandpas и говорят, что у нас есть три свойства. Для простоты рассмотрим три дедушки с именами:

Давайте сделаем их (назначить модификаторы) public , protected и private соответственно. Вы очень хорошо знаете, что protected и private члены не могут быть доступны вне класса. Теперь давайте противоречим утверждению, используя отражение.

Код

 # Scenario 1: without reflection $granpaWithoutReflection = new GrandPas; # Normal looping to print all the members of this class echo "#Scenario 1: Without reflection
"; echo "Printing members the usual way.. (without reflection)
"; foreach($granpaWithoutReflection as $k=>$v) < echo "The name of grandpa is $v and he resides in the variable $k
"; > echo "
"; #Scenario 2: Using reflection $granpa = new ReflectionClass('GrandPas'); // Pass the Grandpas class as the input for the Reflection class $granpaNames=$granpa->getDefaultProperties(); // Gets all the properties of the Grandpas class (Even though it is a protected or private) echo "#Scenario 2: With reflection
"; echo "Printing members the 'reflect' way..
"; foreach($granpaNames as $k=>$v) < echo "The name of grandpa is $v and he resides in the variable $k
"; >
#Scenario 1: Without reflection Printing members the usual way.. (Without reflection) The name of grandpa is Mark Henry and he resides in the variable name1 #Scenario 2: With reflection Printing members the 'reflect' way.. The name of grandpa is Mark Henry and he resides in the variable name1 The name of grandpa is John Clash and he resides in the variable name2 The name of grandpa is Will Jones and he resides in the variable name3 

Распространенные заблуждения:

Пожалуйста, не путайте с приведенным ниже примером. Как вы все еще можете видеть, private и protected члены не могут быть доступны вне класса без использования отражения.

 $granpaWithoutReflections = new GrandPas; print_r($granpaWithoutReflections); 
GrandPas Object ( [name1] => Mark Henry [name2:protected] => John Clash [name3:GrandPas:private] => Will Jones ) 

Функции отладки

print_r , var_export и var_dump являются функциями отладчика. Они представляют информацию о переменной в удобочитаемой форме. Эти три функции покажут protected и private свойства объектов в PHP 5. Статические члены класса не будут показаны.

Больше ресурсов:

извинения за опоздание добавить на этот конво. Можете ли вы сказать мне, почему кто-то будет использовать их? Вы прекрасно объяснили, как они работают и т.д. Я просто хотел бы узнать о преимуществах использования каждого из них. Спасибо

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

Я бы посоветовал вам прочитать объяснение об абстракции, предоставленное Дайрией Лакхера здесь: stackoverflow.com/questions/2558559/… . Это прекрасное дополнение к объяснениям Шанкара Дамодарана.

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

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

Чтобы использовать автомобиль в качестве аналогии, такие вещи, как скорость, передача и направление, будут частными переменными экземпляра. Вы не хотите, чтобы водитель напрямую манипулировал такими вещами, как соотношение воздух/топливо. Вместо этого вы публикуете ограниченное количество действий в качестве общедоступных методов. Интерфейс к машине может включать такие методы, как accelerate() , deccelerate() / brake() , setGear() , turnLeft() , turnRight() и т.д.

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

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

Изменить: Так как кажется, что вы все еще находите среди обучающих объектно-ориентированных концепций (которые намного сложнее освоить, чем любого синтаксиса языка), я высоко рекомендую сбор копии PHP-объектов, шаблонов и практики Мэтта Зандстра. Это книга, которая впервые научила меня эффективно использовать ООП, а не просто преподавать мне синтаксис. Я изучил синтаксис за несколько лет до этого, но это было бесполезно без понимания «почему» ООП.

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

Дэвид А Тейлор написал книги, которые позволили мне по-настоящему понять объекты, не затрачивая на размышления ненужные подробности, например « Объектно-ориентированные технологии: руководство менеджера и бизнес-инжиниринг с использованием объектной технологии» . На обеих страницах по 100 страниц, и каждый из них достаточно прост для чтения во второй половине дня. Конечно, есть Gamma et al. Design Patterns , хотя основной подход можно просто описать как «подкласс того, что вы хотите изменить».

Источник

Оцените статью