Материал: Лекція 6

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Порядок визначення класів має значення. Не можна спочатку визначити клас Programmer, що розширює клас Person, а вже потім сам клас Person. Клас повинен бути визначений перед тим, як він буде використатися (розширюватися).

<?php

class Programmer extends Person{

// визначаємо клас Programmer, що розширює Person

var $langs = array ("Lisp");

function Programmer(){

$this->make_person("Іван","Петров"); }

}

?>

Приклад 6.4. Використання конструктора

5 Оператор ::

Іноді усередині опису класу виникає необхідність послатися на функції або змінні з базового класу. Буває, що потрібно посилатися на функції в класі, жоден представник якого ще не створений. Як бути в такому випадку? В PHP4 для цього існує спеціальний оператор "::"

Наприклад, от так можна викликати в описі класу Programmer функцію show_name() з базового класу Person і функцію say_hello(), задану в описі класу Programmer, коли жоден об’єкт цього класу ще не був створений:

<?php

class Person { // визначаємо клас Особи

var $first_name;

var $last_name;

function Person($t,$a){ // конструктор

$this->first_name = $t;

$this->last_name = $a; }

function show_name(){

// метод відображає інформацію про осіб

echo ("Мене звуть, " . $this->first_name . " " . $this->last_name . "!<br>");}

}

class Programmer extends Person{

// визначаємо клас Programmer, що розширює Person

function set_lang($new_lang){

// метод додає ще одну мову до списку відомих

$this->langs[] = $new_lang;

Person::show_name();

// викликаємо функцію з базового класу

echo "И я знаю тепер ще й " . $new_lang; }

function show_name(){

echo ("Я програміст, " . $this->first_name . " " . $this->last_name . "!<br>");

}

function say_hello(){

echo "Привіт!<br>";

}

}

Programmer::say_hello();

// викликаємо функцію, коли ні один об’єкт її класу ще не створений

$new_progr = new Programmer("Вася","Сидоров");

$new_progr->set_lang("PHP");

?>

У результаті роботи цієї програми одержимо наступне:

Привіт!

Мене кличуть Вася Сидоров!

І я знаю тепер ще й PHP

За допомогою команди Programmer::say_hello(); ми викликаємо функцію say_hello класу Programmer як таку, а не як метод, застосовуваний до об’єкта даного класу. У цей момент змінних класу немає. Тому функції, викликувані до створення об’єкта, не можуть користуватися змінними класу й конструкцією this, але можуть користуватися локальними й глобальними змінними.

У визначенні класу Programmer ми перевизначили функцію show_name(), тому викликати функцію show_name() з базового класу Person можна тільки за допомогою оператора "::" Загалом кажучи, усередині визначення класу ми можемо викликати будь-які методи й властивості, задані в його базовому класі за допомогою звичайного $this, якщо тільки породжений клас не перевизначає ці властивості й методи, як у нашому прикладі.

6 Оператор parent

У наведеному вище прикладі, звертаючись до базового класу, ми використали його ім’я (ми писали Person::show_name() ). Це не зовсім зручно, тому що ім’я класу або ієрархія класів може змінитися, і тоді доведеться переписувати код описів всіх класів для того, щоб привести використовувані в них імена у відповідність із новою ієрархією. Щоб уникнути подібної ситуації, замість імені базового класу потрібно використати ключове слово parent (наприклад, parent::show_name() ). Parent посилається на клас, прописаний після extends в оголошенні вашого класу. Тому якщо раптом ієрархія класів зміниться, то досить буде внести зміни в імена, зазначені після extends в описах класів.

Об’єктна модель PHP5

Крім нової назви для конструкторів і появи деструкторів в PHP5 відбулося ще досить багато змін. Ми не будемо обговорювати їх докладно, тільки опишемо загалом. Основна зміна - це передача значень параметрів класу по посиланню й присвоєння об’єктів по посиланню, а не за значенням, як це було в PHP4. В PHP5 якщо створюються два рівні змінні типи об’єкт, то вони вказують на одне значення й змінюються одночасно (ми наводили схожий приклад зі змінними строкового типу). У зв’язку із цим з’явився новий механізм для створення копій об’єктів - так називане клонування. В PHP4 всі методи й змінні класу доступні ззовні, тобто вони завжди є відкритими. В PHP5 змінні й методи можна робити відкритими (доступними отовсюду), закритими (доступними тільки усередині класу ) і захищеними (доступними усередині класу й у його похідних класах ). Крім того, з’явилася можливість створювати інтерфейси й абстрактні класи й багато чого іншого. У цілому об’єктна модель в PHP5 значно вдосконалена для більше точної відповідності объектно-ориентированной парадигмі програмування.

Рішення завдання

Отже, ми хотіли на вибір користувача генерувати форму для уведення опису статті або людини й відображати дані, уведені в цю форму. Спробуємо вирішити це завдання, використовуючи объектно-ориентированный підхід. Для початку створимо форму, де користувач вибирає, що він хоче створити, - опис статті або людини (точніше, це будуть дві форми):

<form action="task1.php">

Створити опис статті: <input type=submit

name=art_create

value="Create Article">

</form>

<form action="task1.php">

Створити опис особистості: <input

type=submit name=pers_create

value="Create Person">

</form>

Тепер напишемо файл для обробки цих форм. У ньому створимо два класи - статті й особистості. У кожного класу є метод для ініціалізації його змінних і метод для відображення об’єктів даного класу. При рішенні завдання будуть використані дві функції, убудовані в PHP для роботи із класами й об’єктами. Це функція get_class (об’єкт), що повертає ім’я класу, екземпляром якого є об’єкт, переданий їй як параметр. І функція get_class_vars (ім’я класу ), що повертає масив всіх властивостей класу і їхніх значень за замовчуванням. Аналогічно можна одержати масив імен всіх методів класу: get_class_methods (ім’я класу )

<?php

/* Створюємо класи Статей й Особистостей. Стаття має заголовок, автора й опис. Особистість має ім’я, прізвище й e-mail */

class Article {

var $title;

var $author;

var $description;

// метод, що привласнює значення атрибутам класу

function Article($t="Назва відсутнє",

$a="Автор відсутній",

$d="Опис відсутнє"){

$this->title = $t;

$this->author = $a;

$this->description = $d;

}

//метод для відображення екземплярів класу

function show(){

$art = "<h2>$this->title</h2><font

size=-1>$this->description</font><p>Автор:

$this->author</p>";

echo $art;

}

}

// Визначення класу Особистостей

class Person {

var $first_name;

var $last_name;

var $email;

//метод, що привласнює значення атрибутам класу

function Person($t="Ім’я не уведене",

$a="Прізвище не уведене",$d="Email не зазначений"){

$this->first_name = $t;

$this->last_name = $a;

$this->email = $d;

}

//метод для відображення екземплярів класу

function show(){

$art = "<h2>$this->first_name</h2><font

size=-1>$this->last_name</font><p>e-mail:

$this->email</p>";

echo $art;

}

}

// Далі треба властиво створення й відображення екземплярів обраного класу

if (isset($_GET["art_create"])){ //Якщо була обрана стаття

$art = new Article; // створюємо представника класу статей

$art_vars = get_class_vars(get_class($art));

//які аргументи цього класу потрібно задати

Make_form($art,$art_vars,"art_create"); //виклик функції створення форми

if (isset($_GET["create_real"])){ Show_($art_vars); }

// якщо дані цієї форми відправлені, то викликаємо функцію показу

}

//т же саме, якщо була обрана особистість

if (isset($_GET["pers_create"])){

$art = new Person;

$art_vars = get_class_vars(get_class($art));

Make_form($art,$art_vars,"pers_create");

if (isset($_GET["create_real"])){ Show_($art_vars); }

}

// функція створення форми

function Make_form($art,$art_vars,$glob){

$str = "<form>"; // html код форми записується у рядок $str

//перебираємо список змінних класу об’єкта $art

foreach ($art_vars as $var_name => $var_value){

$str .="$var_name<input type=text name=$var_name><br>";

//створюємо елемент форми з ім’ям властивості класу

}

$str .= "<input type=hidden name=$glob>"; // щоб не забути, що ми створюємо

$str .= "<input type=submit name=create_real

value=‘Create and Show’></form>";

echo "$str"; // виводимо форму

}

// функція показу об’єкта

function Show_($art_vars){

global $art; //використається глобальне ім’я об’єкта

$k = count($art_vars); //число властивостей класу (змінних у формі)

$p=0; //допоміжна змінна

foreach ($art_vars as $name => $value){

$p++;

if ($_GET["$name"]=="") $val= $art->$name;

else $val = $_GET["$name"];

if ($p<>$k) $par .=‘"‘. $val.’",’;

else $par .=‘"‘. $val.’"‘;

}

$const=get_class($art);

$par = ‘$art->‘.$const ."(" .$par.");";

/* тепер $par являє собою php-код для виклику методу класу $art, споконвічно записаного в $par. наприклад, $art->Person(‘Vasia’,’Petrov’,’vas@intuit.ru’); */

eval($par); // функція eval виконує код, утримується в $par

$art->show();

}

?>

Листинг 6.6. Використання об’єктно-орієнтованого підходу

Висновок

Отже, ми вивчили основні поняття об’єктної моделі, використовуваної в мові PHP. Були описані правила створення класів й їхніх представників-об’єктів, способи завдання початкових значень змінним класу, способи одержання значень властивостей і виклик методів класів.

Контрольні питання

  1. Дайте визначення об’єкту.

  2. Дайте визначення класу.

  3. Що входить в опис класу?

  4. Для чого використовується ключове слово this?

  5. Які існують обмеження на імена класів?

  6. Яким чином ініціалізуються змінні класу?

  7. Як створюється об’єкт класу?

  8. Що таке успадкування? Яким чином відбувається успадкування в мові РНР?

  9. Що таке механізм розширення? В чому сенс його використання?

  10. Що таке оператор "::"? В чому сенс його використання?

  11. Що таке оператор "parent"? В чому сенс його використання?

10