Полиморфизм методов

Задача
Необходимо передать управление тому или иному коду в зависимости от количества и типа аргументов, переданных методу.

Решение
PHP не поддерживает полиморфизм методов в качестве встроенной функциональности. Однако можно его эмулировать посредством раз-личных функций проверки типа. Следующая функция, combine(), использует функции is_numeric(), is_string(), is_array() и is_bool():

// функция combine() складывает числа, соединяет строки, объединяет массивы
// и выполняет операцию AND над битовыми и логическими аргументами
function combine($a, $b) {
if (is_numeric($a) && is_numeric($b)) {
return $a + $b;
}
if (is_string($a) && is_string($b)) {
return "$a$b";
}
if (is_array($a) && is_array($b)) {
return array_merge($a, $b);
}
if (is_bool($a) && is_bool($b)) {
return $a & $b;
}
return false;
}

Обсуждение
PHP не позволяет объявлять тип переменной в прототипе метода, поэтому он не может реализовать условное выполнение различных методов на основе их сигнатур, как это делается в Java и C++.


Вместо этого можно написать одну функцию и использовать оператор switch, чтобы вручную восстановить эту функциональность.

Например, PHP позволяет редактировать образы с помощью GD. Удобно, если класс образа способен передать или местоположение образа (удаленное или локальное) или дескриптор, который PHP назначает существующему потоку образа. В примере 7.2 показан класс pc_Image, который именно это и делает.

Пример 7.2. pc_Image class
class pc_Image {
var $handle;
function ImageCreate($image) {
if (is_string($image)) {
// простое определение типа
// путем захвата суффикса файла
$info = pathinfo($image);
$extension = strtolower($info['extension']);
switch ($extension) {
case 'jpg':
case 'jpeg':
$this->handle = ImageCreateFromJPEG($image);
break;
case 'png':
$this->handle = ImageCreateFromPNG($image);
break;
default:
die('Images must be JPEGs or PNGs.');
}
} elseif (is_resource($image)) {
$this->handle = $image;
} else {
die('Variables must be strings or resources.');
}
}
}

В данном случае любая переданная строка трактуется как путь к файлу, поэтому мы используем функцию pathinfo() для перехвата расширения файла.


Как только расширение становится известным, мы пытаемся определить, какая из функций ImageCreateFrom() безошибочно открывает образ и создает дескриптор.

Если это не строка, то мы обращаемся непосредственно к потоку, который имеет тип resource. Поскольку нет необходимости проводить преобразование, мы присваиваем поток непосредственно переменной $handle. Естественно, применение этого класса при разработке программного обеспечения позволяет добиться более надежного определе-
ния и обработки ошибок.

Полиморфизм методов также позволяет вызывать методы с различным количеством аргументов. Код, который определяет количество аргументов внутри метода, идентичен тому, как происходит обработка функций с переменным количеством аргументов с помощью func_num_args().

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Динамическая реализация объекта
Динамическое создание класса
Добавление свойств в базовый объект
Доступ к переопределенным методам
Клонирование объектов

Вернуться в раздел: PHP / 7. Классы и объекты