Web

В чем разница между public, protected и private доступом?

Когда и зачем мне следует использовать publicprivate и 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-сервисов
Web

Идеи и полезные книги по разработке высоконагруженных web-сервисов

Web

Как поместить информацию в контроллер Laravel 8

Web

Как использовать тернарный оператор (?:) в PHP как сокращение «if/else»

Web

Копируются ли массивы в PHP как значения или как ссылки на новые переменные при передаче в функции

×