Слава Україні!

Абстрактные классы в php

Пример создания и реализации абстрактного класса на php
26-го грудня 2017, 23:12

Абстрактный класс являет собой базовый класс, не предназначенный для создания его экземпляров. Основной смысл и назначение абстрактных классов заключается в расширении возможностей его дочерних классов.

Создание абстрактного класса

Чтобы сделать класс абстрактным, нужно перед объявлением класса поставить идентификатор: abstract.

Рассмотрим, всю цепочку взаимодействия классов, на примере упрощенного абстрактного класса `Char`, характерного для большинства игр жанра RPG


abstract class Char {
    public  $race; // раса
    public  $height; // рост
    public  $weight; // вес
    public  $aggressive; // статус (агресивный, добрый)

    //поведение
    abstract public function  behavior($action);

    //инициализация
    public function  init($arr){

        $this->race       = $arr['race'];
        $this->height     = $arr['height'];
        $this->weight     = $arr['weight'];
        $this->aggressive = $arr['aggressive'];
    }

    // вывод данных
    public function  print_data(){
        echo "
"; print_r($this); } }

Задача класса состоит в реализации базовых свойств любого персонажа в RPG игре.

К базовым свойствам присущим любой особи можно отнести: расу, рост, вес, статус, местоположение и т.д.

Свойства персонажа будут инициализироваться в стандартной базовой функции init($arr);

В классе присутствует абстрактный метод behavior(), необходимый для задания индивидуального поведения каждого из объектов.

Идентификатор abstract, перед объявлением функции говорит о том, что данная функция должна быть обязательно определена в классе потомке.

Использование абстрактного класса

Для использования заданных базовых свойств и методов класса Char, нужно унаследовать их специальным идентификатором при объявлении класса потомка.


// Класс описывающий первого персонажа - Эльфа
class Elf extends Char{
    public function __construct($arr){
        $this->init($arr);
    }

    //Поведение эльфа
    public function  behavior($action){
        if($action==1){
            $this->aggressive="yes";
        } else {
            $this->aggressive="no";
        }
        return $action;
    }
}
 

Данный класс наследует все методы и свойства базового класса Char, а также определяет новое поведение для объекта этого класса. Т.е. другими словами, дописывается логика абстрактного метода. В данном примере реализуется смена статуса персонажа, при получении события равного единице. Если обработчик поведения подучает событие = 1 то персонаж становится агресивным.

Представим, что мы хотим иметь два вида персонажей в нашей игре с разным поведением на одно и тоже событие. С помощью абстрактных классов реализовать задуманное проще простого. Для этого создадим новый класс Dwarf, в котором прописываем новое поведение для метода behavior().


// Класс описывающий второго персонажа - Гнома
class Dwarf extends Char{

    public function __construct($arr){
        $this->init($arr);
    }

    public function  behavior($action){
        if($action==1){
            echo "
Громкий клич, призывающий к бою."; } return $action; } }

В данном случае при получении события равному единице, персонаж данного класса издаст боевой клич, призывающий к бою. Конечно, никакого звука не будет, мы просто выведем в на страницу текстовое сообщение.

Абстрактный класс и классы потомки определенны, давайте проверим их работоспособность.

Создадим объект класса `Elf`, передав его конструктору необходимые данные.


$char = new Elf(array(
    "race"=>"elf",
    "height"=>"185 cm",
    "weight"=>"60 kg",
    "aggressive"=>"no",
));

$char->print_data();
// Elf Object([race] => elf [height] => 185 cm [weight] => 60 kg [aggressive] => no)
 

Заставим эльфа разозлиться, и передадим событие равное единице в метод обрабатывающий поведение эльфа:

$char->behavior(1);
Проверим повлияли ли наши действия на эльфа

$char->print_data();
// Elf Object([race] => elf [height] => 185 cm [weight] => 60 kg [aggressive] => yes)

Все верно, свойство aggressive приняло значение yes и теперь данный объект является агрессивным.

Создадим еще одного персонажа - гнома


$dwarf = new Dwarf(array(
    "race"=>"dwarf",
    "height"=>"150 cm",
    "weight"=>"80 kg",
    "aggressive"=>"no",
));

// Проделаем с ним тоже, что и с эльфом:

$dwarf->print_data();
$dwarf->behavior(1);
$dwarf->print_data();

# Dwarf Object([race] => dwarf [height] => 150 cm [weight] => 80 kg [aggressive] => no)
# Громкий клич, призывающий к бою.
# Dwarf Object([race] => dwarf [height] => 150 cm [weight] => 80 kg [aggressive] => no)

Подведем итоги

Итак, абстрактный класс - это очень удобный инструмент для расширения возможностей того или иного объекта.

Абстрактные классы не должны содержать реализации метода — они только описывают интерфейс метода. Методы могут быть как обычные так и абстрактные.

Любой дочерний класс абстрактного класса должен включать в себя реализацию всех абстрактных методов родителя или сам должен быть абстрактным. Если этого не сделать, PHP выдаст ошибку.

Важлива інформація

Міністерство оборони
України
з 24.02 по 07.02
втрати противника
орієнтовно склали:
846650 ( +1340 ) особового складу
9975 ( +10 ) танків
20755 ( +18 ) бойових бронемашин
22785 ( +32 ) артилерійських систем
1271 ( +0 ) РСЗВ
1056 ( +1 ) засоби ППО
369 ( +0 ) літаків
331 ( +0 ) гелікоптерів
36307 ( +96 ) автомобільної техніки
28 ( +0 ) кораблі / катери
3054 ( +0 ) крилаті ракети
24301 ( +116 ) БПЛА
3738 ( +1 ) спец. техніки
4 ( +0 ) установок ОТРК/ТРК
1 ( +0 ) підводні човни