Page 70 - 4636
P. 70
тими ж самими значеннями атрибутів. Ви можете змінити цю поведінку. Якщо вам необхідно
нестандартна поведінка clone, створіть у базовому класі метод з ім'ям __clone(). Цей метод,
схожий на конструктор або деструктор, не викликається безпосередньо. Він викликається, коли
використовується ключове слово clone, як показано вище. Усередині методу __clone() можна
визначити необхідні дії по копіюванню. Дуже важлива властивість __clone() полягає в тому, що
цей метод викликається після створення точної копії стандартним способом, тобто на даному етапі
можна змінювати тільки те, що потрібно. Найчастіше в __clone() додається функціональність, яка
перевіряє коректність копіювання атрибутів класу, оброблюваних як посилання. Якщо ви створюєте
копію класу, що містить посилання на якийсь об'єкт, і потрібно, щоб цей об'єкт був скопійований, дані
дії повинні бути додані в __clone(). Іноді необхідно виконати якісь інші дії, наприклад, оновити
базу даних на основі інформації, що зберігається в екземплярі класу.
Використання абстрактних класів
У РНР також доступні абстрактні класи, для яких не можна створювати екземпляри, і абстрактні
методи, які забезпечують тільки сигнатуру методу, без його реалізації, як показано нижче:
abstract, operationX($paraml, $param2);
Будь-який клас, що містить абстрактні методи, повинен бути абстрактним:
abstract class А {
abstract function operationX($paraml, $param2);}
Основні застосування абстрактних методів і класів пов'язані з побудовою складної ієрархії класів, в
якій кожен підклас повинен містити та ігнорувати певні методи; цього ж можна досягти і за
допомогою інтерфейсів.
Перевантаження методів з допомогою методу _call()
Раніше ми стикалися з кількома методами класу спеціального призначення, імена яких починалися
з двох підкреслень (__): __get(), __set(), __construct() і __destruct(). Ще одним
прикладом такого методу може служити метод __call(),який використовується у РНР для
перевантаження методів. Перевантаження методів характерна для багатьох об'єктно-орієнтованих мов,
однак вона не настільки корисна у РНР, оскільки в основному тут застосовуються гнучкі типи і прості
в реалізації необов'язкові функціональні параметри. Для використання перевантаження функцій
потрібно реалізувати метод __call(), як показано в прикладі нижче:
public function __call($method, $p) {if ($method == "display") {
if (is_object($p[0])) {$this->displayObject ($p[0]);
} else if (is_array($p[0])) {$this->displayArray($p[0]);} else {$this-
>displayScalar($p[0]); } }}
Метод__call() приймає два параметри. Перший параметр містить ім'я викликаного методу, а
другий - масив параметрів, переданих цьому методу. У тілі __саll() приймається рішення про те,
який конкретно метод повинен бути викликаний. У даному випадку, якщо методу display()
переданий об'єкт, викликається метод displayObject(), якщо переданий масив викликається
методомdisplayArray(), а у всіх інших випадках - метод displayScalar(). Для виклику
показаного вище коду спочатку потрібно створити примірник клас, що містить метод __саll()
(нехай він називається overload), а потім звернутися до методу display() :
$ov = new overload; $ov->display(array(1, 2, 3)); $ov->display(’кіт');
Перший виклик display() призведе до виконання displayArray(), а другий виклик - до
виконання displayScalar(). Для того щоб цей код працював, вам не потрібна жодна
display().
Використання autoload()
Наступною спеціальною функцією є __autoload(). Це не метод класу, а стандартна функція, яка
повинна оголошуватися за межами будь-яких оголошень класів. Якщо її реалізувати, вона буде
автоматично викликатися при спробі створення екземпляра неоголошеного класу. Основне
призначення __autoload() полягає у включенні або витребуваннявсіх файлів, необхідних для
створення екземплярів необхідного класу. Розглянемо такий приклад:
function __autoload($name) { include_once $name.".php";}
67