Есть некоторый класс:
class a {
private $_a;
function getA() {
return $this->_a;
}
}
Вопрос корифеям объектно-ориентированного программирования на PHP. Как сделать, чтобы класс спокойно себя чувствовал в подобных операциях:
$obj = new a();
$obj = 3;
echo $obj->getA(); // 3
$obj + 4;
echo $obj->getA(); // 7
$obj - 7;
echo $obj->getA(); // 0
$arr = array(1, 2, 3);
if (array_key_exist($obj, $arr)) echo $arr[$obj];
// и. т. д.
В С++, к примеру, такая возможность обеспечивается перегрузкой операторов (operator).
Спустя 19 минут, 21 секунда (20.04.2012 - 09:32) glock18 написал(а):
в пыхе нет перегрузки операторов
Спустя 5 минут, 22 секунды (20.04.2012 - 09:38) yuriy написал(а):
Эхх. Хреново. Очень бы они сейчас пригодились. (
Спустя 1 день, 11 часов, 6 минут, 9 секунд (21.04.2012 - 20:44) SlavaFr написал(а):
большенство языков прекрасно обходится без переписи операторов.
почему ты не можеш без этого обойтись?
почему ты не можеш без этого обойтись?
Спустя 10 часов, 14 минут, 37 секунд (22.04.2012 - 06:58) T1grOK написал(а):
Потому что человек работал с языком, в котором по человечески реализовано ООП. После C++ (си-плюс-плюсного) ООП, пхп-ешное ООП бедное и жалкое(по сути то так и есть).
![smile.gif](http://phpforum.ru/html/emoticons/smile.gif)
Спустя 2 часа, 8 минут, 23 секунды (22.04.2012 - 09:07) glock18 написал(а):
Цитата (SlavaFr @ 21.04.2012 - 18:44) |
большенство языков прекрасно обходится без переписи операторов. почему ты не можеш без этого обойтись? |
многие языки вообще без классов обходятся, а где-то и циклов в привычном виде нет. это же не значит, что без них нужно обходиться.
а вообще фича с перегрузкой операторов одна из многих мега-фич cpp, которые реально полезны
Спустя 11 часов, 42 минуты, 24 секунды (22.04.2012 - 20:49) SlavaFr написал(а):
Цитата (T1grOK @ 22.04.2012 - 04:58) |
Потому что человек работал с языком, в котором по человечески реализовано ООП. |
Можно долго спорить. Например в C++ можно без классов и объектов обходится, что в объект ориентированных языках как Java просто не возможно.
Цитата (glock18 @ 22.04.2012 - 07:07) |
а вообще фича с перегрузкой операторов одна из многих мега-фич cpp, которые реально полезны |
в чем они реально полезны?
Неужели
$obj->add(5);
хуже чем
$obj += 5;
а в случае ошибок разбиратся, что $оbj не является простым типом и что надо искать функцию operator+= ?
воимя чего?
чтоб выглядело как у школьника в тетрадеке?
Другие языки не переняли это мега-фич, не по тому, что они не в состоянии это делать, а по тому, что они сочли это не особо нужным.
не смотря на мое личное мнение к перепеси операторов, возможность их переписывать имеется всеровно
http://pecl.php.net/package/operator
Спустя 1 день, 12 часов, 53 минуты, 19 секунд (24.04.2012 - 09:42) yuriy написал(а):
Спасибо, Слава! Уже кое-что. Осталось выяснить установлен ли данный пакет на хостинге, да и пару примеров посмотреть не мешало бы. На ресурсе, который ты указал, что-то примеров не нашёл.
Спустя 43 минуты, 40 секунд (24.04.2012 - 10:26) SlavaFr написал(а):
Цитата (yuriy @ 24.04.2012 - 07:42) |
Спасибо, Слава! Уже кое-что. |
ты мне лучше раскажи зачем тебе это нужно?
Спустя 14 минут, 51 секунда (24.04.2012 - 10:41) glock18 написал(а):
Цитата (SlavaFr @ 24.04.2012 - 08:26) |
ты мне лучше раскажи зачем тебе это нужно? |
я могу только привести пример (не берусь утверждать, что у ТС что-то из этого разряда). В C++ есть 3 типа (мб и больше даже) для работы со строками - char*, string, CString - последние два классы. Я когда-то писал обертку небольшую для работы со строками, где основная роль как раз отводилась работе с операторами. Вообще говоря обертка писана была с целью сжульничать при сдаче лабораторок, но смысл тем не менее был еще таким: объединить всю работу со строками в один интерфейс, который может вести себя как string и char* без необходимости ручной конвертации типа. Вот как-то так, вполне себе нормальное применение, на самом деле.
В данной ситуации, перегрузка операторов вполне применима для воплощения паттерна стратегии, примерно так же, как магический метод __toString позволяет получить строку из объекта, а оператор позволяет с ним работать с каким-либо отождествленным типом, будь то строка или число.
Спустя 14 минут, 47 секунд (24.04.2012 - 10:56) yuriy написал(а):
SlavaFr Да тут наткнулся на одну задачу. Вот, к примеру, есть некоторая функция, которая имеет в теле такой код:
Раньше, я подавал в $key число. Но потом задача усложнилась и в $key уже находится не число, а объект. И чтобы всё выглядело натурально, захотелось научить объект притворятся числом. __toString() не подходит в данном случае, а перегрузка оператора, возможно поможет. Ещё очень полезно при реализации интерфейса ArrayAccess, когда функция
Возвращает объект, который тоже реализует ArrayAccess. Тогда можно делать всякие хорошие штуки. К примеру:
// $key - параметр функции
if (array_key_exist($key, $this->_config)) {
// ...
}
Раньше, я подавал в $key число. Но потом задача усложнилась и в $key уже находится не число, а объект. И чтобы всё выглядело натурально, захотелось научить объект притворятся числом. __toString() не подходит в данном случае, а перегрузка оператора, возможно поможет. Ещё очень полезно при реализации интерфейса ArrayAccess, когда функция
/**
* public function offsetGet()
*
* @param mixed $key
* @return mixed
*/
public function offsetGet($key) {
return $obj;
}
Возвращает объект, который тоже реализует ArrayAccess. Тогда можно делать всякие хорошие штуки. К примеру:
// offsetGet() объекта $obj вернула объект
$obj['count']++;
echo $obj['count']['protected'];
Спустя 46 минут, 49 секунд (24.04.2012 - 11:43) SlavaFr написал(а):
Цитата (yuriy @ 24.04.2012 - 08:56) |
Раньше, я подавал в $key число. Но потом задача усложнилась и в $key уже находится не число, а объект. И чтобы всё выглядело натурально, захотелось научить объект притворятся числом. __toString() не подходит в данном случае, а перегрузка оператора, возможно поможет |
ну а что мешает $арраы[$keyobject->intValue()] вызывать?
Стоит из за этого усложнять собственный код, да еще так, чтоб скрывать от других тип твоего ключа?
Цитата (glock18 @ 24.04.2012 - 08:41) |
В данной ситуации, перегрузка операторов вполне применима для воплощения паттерна стратегии, примерно так же, как магический метод __toString позволяет получить строку из объекта, а оператор позволяет с ним работать с каким-либо отождествленным типом, будь то строка или число. |
это все удобство в каком то конкретном и редком случае
Да удобней зделать
echo $object;
но руки не отпадут если тоже вызвать методом
echo $object->strValue();
с одной стороны нужно немного больше писатгь, зато всем понятно, что мы работаем с объектом а не с простым типом.
Спустя 8 минут, 58 секунд (24.04.2012 - 11:52) glock18 написал(а):
Цитата (SlavaFr @ 24.04.2012 - 09:43) |
Да удобней зделать echo $object; но руки не отпадут если тоже вызвать методом echo $object->strValue(); с одной стороны нужно немного больше писатгь, зато всем понятно, что мы работаем с объектом а не с простым типом. |
а я говорил вовсе не об удобстве. если у вас есть переменная $string, которая может быть как простой строкой, так и любым объектом, перегружающим работу над строковыми операторами. второе выбросит ошибку при работе со строкой
Спустя 4 минуты, 22 секунды (24.04.2012 - 11:56) glock18 написал(а):
Цитата (SlavaFr @ 24.04.2012 - 09:43) |
это все удобство в каком то конкретном и редком случае |
я и не говорил, что это нужно часто. тем не менее, нужно оно бывает. как скажем, даже банальный синглтон или mvc (он и вообще в пределах целого приложения реализуется всего один раз) - оба используются не везде далеко, но используются. А если есть разумные случаи, когда фича нужна, то она нужна. выше я привел как раз такой пример, он вообще говоря к пыху имеет отношение меньшее, чем к тому же C++, но и в пыхе эта возможность могла бы быть применена с пользой.
весьма удачный пример касательно редкости - late static bindings, вот они реально то нужны вообще достаточно редко (а то и очень редко). но штука очень полезная
Спустя 11 минут, 35 секунд (24.04.2012 - 12:07) yuriy написал(а):
Ещё одна вещь, которую Слава не учитывает - это рефакторинг кода. Если функция раньше работала с int, а теперь мы вместо int незаметно для неё подсовываем object, то игра стоит свеч.
Спустя 1 час, 17 минут, 31 секунда (24.04.2012 - 13:25) SlavaFr написал(а):
Цитата (yuriy @ 24.04.2012 - 10:07) |
Ещё одна вещь, которую Слава не учитывает - это рефакторинг кода. Если функция раньше работала с int, а теперь мы вместо int незаметно для неё подсовываем object, то игра стоит свеч. |
игра не стоит свечь. Типы аргументов и ретурна должны быть предсказуемыми и понятными. Самое страшное, что я себе могу представить, так это то, что функция которая должна отдавать интегер передаст мне объект.
Цитата |
весьма удачный пример касательно редкости - late static bindings, вот они реально то нужны вообще достаточно редко (а то и очень редко). но штука очень полезная |
я считаю этот пример не особо подходящим, так как пхп в предыдущих версиях просто не поддерживала правильно наследования статических методов. В нашем случае мы не говорим о "редком и невозможном" имплементирование, а о редком имплементирование которое можно без головной боли реализовать во всех языках программирования включая c++ не применяя переписывания операторв.
Спустя 4 минуты, 38 секунд (24.04.2012 - 13:30) glock18 написал(а):
Цитата (SlavaFr @ 24.04.2012 - 11:25) |
я считаю этот пример не особо подходящим, так как пхп в предыдущих версиях просто не поддерживала правильно наследования статических методов. В нашем случае мы не говорим о "редком и невозможном" имплементирование, а о редком имплементирование которое можно без головной боли реализовать во всех языках программирования включая c++ не применяя переписывания операторв. |
я привел пример выше, и вы согласились, что хотя и редко, но полезно это может быть. дальше я указал на конкретное применение.
в условиях, полиморфизм используется мало, перегрузка операторов действительно не требуется.
2yuriy:
рефакторинг совсем не причем, и здесь SlavaFr абсолютно прав
Спустя 2 минуты, 30 секунд (24.04.2012 - 13:32) Guest написал(а):
Типы аргументов и ретурна и так предсказуемые - стоит взглянуть на сигнатуру функции. ) Речь не о том. Есть куча функций в которые сильно хочется впихнуть объект вместо числа. Так почему бы этого не сделать, если это возможно? А уж если при этом всё будет работать как раньше - то это вообще хорошо. )
Спустя 6 минут, 12 секунд (24.04.2012 - 13:38) glock18 написал(а):
Цитата (Guest @ 24.04.2012 - 11:32) |
Типы аргументов и ретурна и так предсказуемые - стоит взглянуть на сигнатуру функции. ) Речь не о том. Есть куча функций в которые сильно хочется впихнуть объект вместо числа. Так почему бы этого не сделать, если это возможно? А уж если при этом всё будет работать как раньше - то это вообще хорошо. ) |
ну, это приятно, конечно. если вы описание функции поменяете соответственно, разумеется. но дело тут просто в том, что лень переписывать, а не то, что перегрузка требуется исходя из архитектурных требований. кстати, в примере, где вы хотите его использовать с array_key_exists перегрузка операторов не поможет, очевидно. для начала, какой оператор здесь, по-вашему, задействован то?
Спустя 5 минут, 29 секунд (24.04.2012 - 13:44) yuriy написал(а):
Боюсь, что да. В array_key_exists объект впихнуть не удастся. Да и Бог с ним. Зато финт $obj['count']['protected'] и $obj['count']++ очень даже удастся.
_____________
void x;