ООП PHP
Модификаторы доступа
Геттеры и сеттеры
Область видимости: php.net
Модификаторы доступа (области видимости)
Модификаторы доступа
Область видимости свойства, метода или константы (PHP 7.1) может быть определена путем использования следующих ключевых слов в объявлении: public, protected или private.
- public (общедоступный) - свойство или метод доступны отовсюду (в классе, во всех классах-наследниках, из вне класса).
- protected (защищенный) - свойства или методы доступны только в классе, где они объявленны и во всех классах-наследниках. Из вне класса такие свойства или такие методы доступны не будут.
- private (закрытый) - свойства или методы доступны только в том классе, где они объявленны. В наследниках, из вне класса такое свойство или метод доступны не будут и использовать их не получиться.
Модификаторы (области видимости) предназначены для контроля нашего кода.
В классе Product (все файлы - из предыдущего урока "Наследование") создадим новые свойства:
$public , $protected, $private и в индексном файле распечатаем их - debug($book).
Попытаемся обратиться к каждому из свойств.
При попытке обратиться к свойствам $protected и $private из вне класса (index.php) - выводится ошибка.
При обращении к этим свойствам из класса Product - все они выводятся.
При обращении из дочернего класса BookProduct - свойство $private - не доступно.
Обращение к свойствам $public, $protected, $private из класса Product (где они были объявлены):
Файл Product.php
-- файл Product.php --
<?php
class
{
public $name; // наименование товара
public $price; // цена товара
// создадим новые свойства
public $public = 'PUBLIC';
protected $protected = 'PROTECTED';
private $private = 'PRIVATE';
public function ($name, $price)
{
$this -> name = $name;
$this -> price = $price;
// попытаемся обратиться к каждому из свойств внутри класса (все свойства доступны)
($this -> public);
($this -> protected);
($this -> private);
}
}
?>
Обращение к свойствам $public, $protected, $private из дочернего класса BookProduct:
Файл BookProduct.php
-- файл BookProduct.php --
<?php
class extends
{
public $numPages;
public function ($name, $price, $numPages)
{
parent :: ($name, $price);
$this -> numPages = $numPages;
// попытаемся обратиться к каждому из свойств в дочернем классе
($this -> public);
($this -> protected);
//var_dump($this->private); // Неопределенное свойство (свойство не доступно)
}
//...
//...
//...
}
?>
Обращение к свойствам $public, $protected, $private из вне класса (index.php):
Файл index.php
-- файл index.php --
<?php
(-1);
require_once 'classes/Product.php';
require_once 'classes/BookProduct.php'; // подключаем класс BookProduct
function ($data)
{
echo '<pre>' . ($data, 1 ) . '</pre>';
}
$book = new ('Три мушкетера', 20, 1000);
// распечатаем объект
($book);
// попытаемся обратиться к каждому из свойств из вне класса
($book->public);
//var_dump($book->protected); // Не удается получить доступ (свойство не доступно)
//var_dump($book->private); // Неопределенное свойство (свойство не доступно)
//echo $book->getProduct();
?>
В итоге получим:
string 'PUBLIC' (length=6) - обращение внутри класса Product, где свойства объявленны
string 'PROTECTED' (length=9) - обращение внутри класса Product, где свойства объявленны
string 'PRIVATE' (length=7) - обращение внутри класса Product, где свойства объявленны
string 'PUBLIC' (length=6) - обращение к свойствам из дочернего класса BookProduct
string 'PROTECTED' (length=9) - обращение к свойствам из дочернего BookProduct
распечатываем объект (debug($book))
BookProduct Object
(
[numPages] => 1000
[name] => Три мушкетера
[price] => 20
[public] => PUBLIC
[protected:protected] => PROTECTED
[private:Product:private] => PRIVATE
)
string 'PUBLIC' (length=6) - обращение к свойствам из вне класса (index.php)
Часто в интернет-магазинах выводится старая и новая цена или цена со скидкой для товара.
Для примера создадим в классе Product свойство для скидки: public $discount = 10.
В методе getPrice()- получение цены - определим цену с учетом скидки по формуле.
И, соответственно , в информации о продукте(метод getProduct()), запишем цену со скидкой:
- Цена со скидкой: {$this->getPrice()}.
Файл Product.php
-- файл Product.php --
<?php
class
{
public $name;
public $price ;
// создадим свойство для скидки
public $discount = 10 ;
public function ($name, $price)
{
$this -> name = $name;
$this -> price = $price;
}
// метод getProduct() - будет возвращать информацию о товаре.
// информацию о цене со скидкой будем выводить не ($this->price)
// а ($this->getPrice()) - цена с учетом скидки:
public function ()
{
return "<hr><b>О товаре:</b><br>
Наименование: {$this -> name}<br>
Цена со скидкой: {$this -> ()}<br> ";
}
// получение цены по скидке (по формуле)
public function ()
{
return $this -> price - ($this -> discount/100 * $this -> price) ;
}
}
?>
Получим:
BookProduct Object
(
[numPages] => 1000
[name] => Три мушкетера
[price] => 20 // цена товара
[discount] => 10 // скидка
)
// метод getProduct() - раскомментирован
О товаре:
Наименование: Три мушкетера
Цена со скидкой: 18 // цена со скидкой
Кол-во страниц: 1000
Цену без скидки мы можем подсмотреть в коде (при модификаторе - public $price), при модификаторе видимости - private $price или protected это свойство становится недоступным и посмотреть цену можно только через getProduct().
Меняем модификатор видимости с public на protected - чтобы это свойство было доступно в классах-наследниках.
Чтобы можно было показывать не только новую цену (со скидкой), но и старую (без скидки) в классе BookProduct в методе getProduct() запишем:
- $out .= "Цена без скидки: {$this->price}<br>"
Чтобы случайно не преопределить свойство $discount (скидка), правильнее было ставить модификатор privat и приравнять скидку к нулю: private $discount = 0.
Геттеры и сеттеры
Дочерние классы получают доступ к закрытым (приватным) свойствам через метод - сеттер.
Свойство private, в отличии от protected, можно заполнить через какой-нибудь метод (сеттер).
Через геттеры и сеттеры мы получаем доступ к значениям закрытых или скрытых свойств.
Установим в классе Product геттер getDiscount() и сеттер setDiscount($discount).
Метод геттер - получает доступ к некоторому свойству, как правило к приватному или защищенному.
Метод сеттер - позволяет установить закрытое для записи свойство и записать в него некоторое значение.
Эти методы публичные и они доступны в классах-наследниках и установить скидку мы можем
в каком-нибудь методе, скажем, в конструкторе (в классе BookProduct):
$this->setDiscount(5) - устанавливаем скидку в 5%.
Посмотреть скидку мы можем, вызвав ее в методе getProduct() класса BookProduct:
$out .= "Скидка: {$this->getDiscount()}%<br>".
Вне класса (файл index.php), при желании, мы можем скидку посмотреть(через геттер):
echo $book ->getDiscount().
Плюсы использования геттеров и сеттеров заключаются в том, что можем контролировать тип данных (декларация возвращаемого значения (для геттеров) и декларация устанавливаемого значения (для сеттеров)).
В свойстве $name можно поставить модификатор private, чтобы случайно его не перезаписать.
Файл Product.php
-- файл Product.php --
<?php
class
{
// в свойстве $name можно поставить модификатор private,
// чтобы случайно его не перезаписать
// меняем модификатор видимости с public на private и при попытке
// вывести её вне класса произойдет ошибка - "Неопределенное свойство... "
private $name;
// $price - чтобы это свойство было доступно в классах-наследниках
// меняем private на protected
protected $price ;
// создадим свойство для скидки
// чтобы случайно не преопределить свойство $discount (скидка),
// правильнее было ставить модификатор private
// дочерние классы получают доступ к закрытым (приватным)свойствам через метод - сеттер
// свойство private, в отличии от protected, можно заполнить через какой-нибудь
// метод (сеттер)
private $discount = 0 ;
public function ($name, $price)
{
$this -> name = $name;
$this -> price = $price;
}
// метод getProduct() - будет возвращать информацию о товаре.
// информацию о цене со скидкой будем выводить не ($this->price)
// а ($this->getPrice()) - цена с учетом скидки:
public function ()
{
return "<hr><b>О товаре:</b><br>
Наименование: {$this -> name}<br>
Цена со скидкой: {$this -> ()}<br> ";
}
// общие гетеры:
public function ()
{
return $this -> name ;
}
// получение цены по скидке (по формуле)
public function ()
{
return $this -> price - ($this -> discount/100 * $this -> price) ;
}
// дочерние классы получают доступ к закрытым (приватным)свойствам через метод - сеттер
// через геттеры и сеттеры мы получаем доступ к значениям закрытых или скрытых свойств
// эти методы публичные и они доступны в классах-наследниках
// и установить скидку мы можем в каком-нибудь методе,
// скажем, в конструкторе (BookProduct)
// метод геттер - получает доступ к некоторому свойству,
// как правило к приватному или защищенному
public function ()
{
return $this -> discount ;
}
// метод сеттер - позволяет установить закрытое для записи свойство
// и записать в него некоторое значение
public function ($discount)
{
$this -> discount = $discount ;
}
}
?>
Файл BookProduct.php
-- файл BookProduct.php --
<?php
class extends
{
public $numPages;
public function ($name, $price, $numPages)
{
parent :: ($name, $price);
$this -> numPages = $numPages;
$this -> (5); // устанавливаем скидку в 5%
}
public function ()
{
$out = parent :: ();
$out .= "Цена без скидки: {$this -> price}<br>" ;
$out .= "Кол-во страниц:: {$this -> cpu}<br>" ;
$out .= "Скидка: {$this -> ()}%<br>" ; // дописываем скидку
return $out;
}
public function ()
{
return $this -> numPages ;
}
}
?>
Файл index.php
-- файл index.php --
<?php
(-1);
require_once 'classes/Product.php';
require_once 'classes/BookProduct.php';
function ($data)
{
echo '<pre>' . ($data, 1 ) . '</pre>';
}
$book = new ('Три мушкетера', 20, 1000);
($book);
// получаем информацию о продукте с помощью метода getProduct()
echo $book -> ();
// цену без скидки мы можем подсмотреть в коде при модификаторе - public $price,
// при модификаторе видимости - private $price или protected
// это свойство становится недоступным и посмотреть цену можно только через getProduct()
//echo $book->price ;
// через геттер мы можем посмотреть скидку из вне класса
echo $book -> ();
?>
Выведет:
- debug($book)-
BookProduct Object
(
[numPages] => 1000
[name:Product:private] => Три мушкетера
[price:protected] => 20
[discount:Product:private] => 5
)
- метод getProduct() -
О товаре:
Наименование: Три мушкетера
Цена со скидкой: 19
Цена без скидки: 20
Кол-во страниц: 1000
Скидка: 5%
- метод getDiscount() -
5
Рекомендуется для всех свойств изначально поставить private, а для большинста методов - public.
Постепенно, по необходимости, пожно понижать контроль доступа (для свойств).
Для свойств, которые предполагается использовать в классах-наследниках, можно поставить уже - protected. А для свойств, которые предполагается использовать из вне класса, можно поставить - public.
Для методов, которые являются служебными и пользователю не нужны для работы, можно поставить protected и реже - private.
Содержание папки 9 ("Модификаторы доступа"):
Наверх Наверх