Перегрузка методов и аксессоры в PHP
Опубликовано: 06.09.2018
С помощью перегрузки методов в PHP, можно создать метод с таким же названием, что и в базовом классе, который заменит метод базового класса при вызове.
Модуль 32. Полиморфизм и переопределение методов. Видеокурс по C#
Все методы перегрузки объявляются исключительно только как "public".
Пример перегрузки метода: class base_class { public function method_base() { echo 'Вызван метод "method_base" базового класса'; } } class derivative_class extends base_class { public function method_base() { echo 'Вызван метод "method_base" производного класса'; } } $_new_class = new derivative_class(); $_new_class->method_base();Результатом работы будет вывод фразы "Вызван метод "method_base" производного класса".
Модуль 29. Перегрузка операторов в языке программирования C#
Таким образом, метод base_class::method_base() не вызывается при обращении к объекту производного класса "derivative_class".
Однако в рамках производного класса остаётся возможность вызвать метод базового класса, обратившись к нему при помощи префикса "parent::".
Ниже будет представлен пример перегрузки метода "method_base()", при котором метод производного класса сначала вызывает метод базового класса.
class base_class { public function method_base() { echo 'Вызван метод "method_base" базового класса'; } } class derivative_class extends base_class { public function method_base() { parent::method_base(); echo '<br />Вызван метод "method_base" производного класса'; } } $_new_class = new derivative_class(); $_new_class->method_base();Результат покажет уже две строчки "Вызван метод "method_base" базового класса" и "Вызван метод "method_base" производного класса".
Таким образом, при помощи перегрузки метода можно как расширить метод базового класса, так и полностью заменить его уже новым методом.
Ниже будет продемонстрирован пример перегрузки методов с класса "mysqli":
class connect extends mysqli { public function __construct($_host_base = null, $_user_base = null, $_password_base = null, $_data_base = null) { parent::init(); # Перегружаем метод инициализации, чтобы установить опции; /* - Перегружаем опцию (метод) и устанавливаем таймаут соединения; */ if (!parent::options(MYSQLI_OPT_CONNECT_TIMEOUT, 5)) { die('Error: # Превышен таймаут соединения'); } /* - Прегружаем метод соединения с базой данных, с перегрузкой опции (метода) для установления кодировки ; */ if (!parent::real_connect($_host_base, $_user_base, $_password_base, $_data_base, parent::options(MYSQLI_INIT_COMMAND, 'SET NAMES utf8'))) { die('Connect DataBase Error: #'. mysqli_connect_error() .' : ('. mysqli_connect_errno() .')'); } } // Далее мы создадим свой метод в котором перегрузим метод из базового класса; public function sqlQuery($_Query) { return parent::query($_Query); } } $_Sql = new connect('localhost', 'Юзер', 'Пароль', 'База') or die('Error Class: connect'); $_Sql->sqlQuery('Запрос');В примере конструктор имеет нужные нам опции, при этом из его тела происходит перегрузка методов из базового класса с помощью ключевого слова <parent::>, после чего выполняются действия, специфические для класса "mysqli". Аналогичным образом могут перегружаться любые методы базового класса в производном классе "connect".
Помимо этого в PHP существует ещё два "магических" метода (аксессоры),при помощи которых можно перегрузить свойства, которые вызываются при обращении к свойству класса и при изменении его значения, - это методы "__get()" и "__set()".
Данные методы "__get()" и "__set()" позволяют легко проводить динамическое назначение свойств объектам, а в качестве параметров этим методам передаются имена свойств.
А также, метод "__set()" может получить и значение, которое присваивается указанному свойству. Приведём пример:
class setget { // Член в котором будут храниться перегружамые данные; private $_array = array() ; /* - Выполняем запись данных в недоступные свойства */ private function __set($_Home, $_Value) { $this->_array[$_Home] = $_Value; } /* - Выполняем чтение данных из недоступных свойств */ private function __get($_Home) { return $this->_array[$_Home]; } } $class_ = new setget(); $class_->test = 'Обращение к несуществующему элементу'; echo $class_->test;Как видно из примера, класс "setget" перехватывает обращения к членам и создает соответствующий элемент в массиве $_array.
При попытке присвоить члену значение, создаётся новый элемент в массиве $_array.
Если член в классе уже существует, то аксессоры "__set()" и "__get()" перехватывают обращение к нему, если он имеет спецификатор доступа "private" и не перехватывают, если он имеет спецификатор "public".
Ещё существуют новый метод перегрузки "__callStatic()" который добавлен в PHP 5.3, и метод "__call". Пример:
class callandstatic { // Общее замечание: Значение $_Home регистрозависимо; public function __call($_Home, $_arg) { echo implode(', ', $_arg) . $_Home; } public static function __callStatic($_Home, $_arg) { echo implode(', ', $_arg) . $_Home; } } $class_ = new callandstatic; $class_->_test('Вызов недоступного метода '); callandstatic::_test('Вызов недоступного статического метода '); /* * Начиная только с версии PHP 5.3 иначе будет вызвана ошибка * (Fatal error: Call to undefined method callandstatic::_test()) */$_Home содержит имя метода, а $_arg массив в котором храняться параметры которые передаются из метода $_Home.