Когда и зачем мне следует использовать public, private и protected функции и переменные внутри класса? В чем разница между ними?
Примеры:
// Public
public $variable;
public function doSomething() {
// ...
}
// Private
private $variable;
private function doSomething() {
// ...
}
// Protected
protected $variable;
protected function doSomething() {
// ...
}
Ответ 1
public область видимости используется, чтобы сделать это свойство/метод доступным из любого места, других классов и экземпляров объекта.
private область видимости, если необходимо, чтобы ваше свойство/метод было видно только в его собственном классе.
protected, если вы хотите сделать свое свойство/метод видимым во всех классах, расширяющих текущий класс, включая родительский класс.
Если вы не используете модификатор видимости, свойство/метод будут общедоступными.
Ответ 2
Public:
Когда вы объявляете метод (функцию) или свойство (переменную) как public, к этим методам и свойствам могут получить доступ:
Тот же класс, который его объявил.
Классы, наследующие объявленный выше класс.
Любые внешние элементы вне этого класса также могут получить доступ к ним.
Пример:
<?php
class GrandPa{
public $name='Mark Henry'; // A public переменная
}
// Наследуемый класс
class Daddy extends GrandPa {
function displayGrandPaName() {
return $this->name; // public переменная, которая доступна из наследуемого класса
}
}
$daddy = new Daddy;
echo $daddy->displayGrandPaName();
// Public переменная, которая доступна также из внешнего класса!
$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name;
Protected:
Когда вы объявляете метод (функцию) или свойство (переменную) как protected, к этим методам и свойствам могут получить доступ:
Тот же класс, который его объявил.
Классы, наследующие объявленный выше класс.
Внешние члены не могут получить доступ к этим переменным. «Внешние» в том смысле, что они не являются экземплярами объекта самого объявленного класса.
Пример:
<?php
class GrandPa {
protected $name = 'Mark Henry';
}
class Daddy extends GrandPa {
function displayGrandPaName() {
return $this->name;
}
}
$daddy = new Daddy;
echo $daddy->displayGrandPaName();
$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name; // В результате ошибка
Точная ошибка будет такой:
Неустранимая ошибка PHP: невозможно получить доступ к защищенному свойству GrandPa:: $name
Private:
Когда вы объявляете метод (функцию) или свойство (переменную) как private, к этим методам и свойствам может получить доступ:
Тот же класс, который его объявил.
Внешние члены не могут получить доступ к этим переменным. «Внешние» в том смысле, что они не являются экземплярами объекта самого объявленного класса и даже не являются классами, наследующими объявленный класс.
Пример:
<?php
class GrandPa{
private $name = 'Mark Henry';
}
class Daddy extends GrandPa{
function displayGrandPaName() {
return $this->name;
}
}
$daddy = new Daddy;
echo $daddy->displayGrandPaName();
$outsiderWantstoKnowGrandpasName = new GrandPa;
echo $outsiderWantstoKnowGrandpasName->name; // В результате ошибка
Сообщения об ошибках будут следующими:
Примечание: Неопределенное свойство: Daddy::$name
Неустранимая ошибка: невозможно получить доступ к частному свойству GrandPa::$name
Ответ 3
Обычно хорошей практикой считается установка по умолчанию минимальной требуемой видимости, поскольку это способствует инкапсуляции данных и хорошему дизайну интерфейса. При рассмотрении переменной-члена и видимости метода подумайте о роли, которую член играет во взаимодействии с другими объектами.
Если вы «кодируете интерфейс, а не реализацию», то обычно довольно просто принимать решения о видимости. В общем, переменные должны быть закрытыми или защищенными, если у вас нет веских причин для их раскрытия. Вместо этого используйте общедоступные методы доступа (геттеры/сеттеры) для ограничения и регулирования доступа к внутренним компонентам класса.
Если использовать автомобиль в качестве аналогии, такие вещи, как скорость, передача и направление, будут частными переменными экземпляра. Вы же не хотите, чтобы водитель напрямую управлял такими вещами, как соотношение воздух/топливо. Вместо этого вы предоставляете ограниченное количество действий как общедоступные методы. Интерфейс автомобиля может включать в себя методы, такие как accelerate(), deccelerate()/brake(), setGear(), turnLeft(), turnRight() и т. д.
Водитель не знает и не должен заботиться о том, как эти действия реализуются внутренними компонентами автомобиля, и раскрытие этой функции может быть опасно для водителя и других людей на дороге. Следовательно, хорошая практика разработки общедоступного интерфейса и инкапсуляции данных за этим интерфейсом.
Этот подход также позволяет вам изменять и улучшать реализацию общедоступных методов в вашем классе, не нарушая контракт интерфейса с клиентским кодом. Например, вы можете улучшить метод accelerate(), чтобы он был более экономичным, но использование этого метода осталось бы прежним; клиентский код не потребует изменений, но все равно получит выгоду от повышения эффективности.
Web