Как стать автором
Обновить

Комментарии 30

НЛО прилетело и опубликовало эту надпись здесь
Может я ошибаюсь, но здесь нет множественного наследования =)
Есть что-то вроде "фабрики" чтоли )
Если вы про Factory, то (может я тоже ошибаюсь, не особо силен в шаблонах) вы не правы.
http://php.ru/manual/language.oop5.patte…. Там есть Factory Pattern пример.
Допустим нужно сделать аттачер одних сущностей к другим. У обоих сущностей есть методы setId и getId. Так вот всегда будут срабатывать методы ранее инстанцированных экземпляров.
А может я сам себе противоречу =) Ведь ничто не мешает прямо в этом классе всё попереопределять и дописать ))
А вообще, конечно, полезная штука.
"Требует доработки скорее всего, пока что только набросок на будущее"

Как минимум надо еще __set, __get для переменных классов, ну и как вы правильно заметили, еще необходимо научить класс (скорее всего это будут какие-то соглашения), когда оба наследуемых класса реализуют один метод, или когда оба класса имеют одну и ту же переменную. В общем нюансы есть, возможно нужно посмотреть как эти ситуации разрешаются в том же С++, где множественное наследование вроде бы как есть.
Там есть некий мистический «порядок наследования», который определяет, какой из методов брать.
В C# ещё интереснее сделано с интерфейсами: там можно реализовать интерфейс в классе так, что реализованные методы не достать никак, кроме как приведя тип этого объекта к типу интерфейса, таким образом можно реализовывать два метода с одинаковыми именами для разных интерфейсов в одном классе по-разному.
ага, мне тут уже человек сказал что там около 15 правил наследования.
Мы тут в принципе обсуждаем необходимость множественного наследования как такового. Я когда начинал программировать сталкивался с ситуацией когда хочется унаследоваться от двух классов, сейчас уже таких желаний не возникает, может и не нужно тогда множественное наследование.


А вообще этот код написал вспоминая вопрос на одном из собеседований, типа надо унаследоваться от двух классов, как это лучше организовать
Я считаю что оно нужно. Во всяком случае не лишнее.
хм... все руки не доходили Reflection глянуть... а тут способ вызова произвольных конструкторов.
спасибо!

ЗЫ: почти в тему: где можно найти хорошую документацию по SPL? в мане описаны только Countable, Iterator и ArrayAccess.
php.net/~helly
о, спасибо!
я когда-то это видел, но тогда мне не хватило "документированности" ;)
сейчас - вполне!
Не за что. Там есть чему поучиться. Я про этот раздел узнал в топике про задачки на php, где было предложено реализовать интерфейс ArrayAccess, который мне супер-мега-крутым показался =)
НЛО прилетело и опубликовало эту надпись здесь
не заметил приписки про 7 дней, видимо придется вставить код здесь, но здесь он очень плохо будет смотреться...
сенкс
имхо, коментарии наше всё. тем более если нбросок на будущее =) да и новичкам понятней будет
в этом подходе есть глюки есть глюки.
Если например в классе от которого "наследуемся" есть метод который что-то возвращает by ref, то это работать не будет.
так как call_user_method_array и подобные функции не возвращают by ref
и вообще, чем это просто агрегация, а не множественное наследование.
Если я правильно понял что вы имели ввиду, попробуйте выполнить:


по поводу агрегации ничего сказать не могу. Не нашел такого шаблона. Дайте ссылку
<?php
function a( $param )
{
$param = 'b';
}

$p = 'a';
call_user_func_array( 'a', array( &$p ) );
//a( &$p );

var_dump( $p );
?>
Нет, говорил я не о передаче параметров по ссылке, а о возвращаемом по ссылке значении.
Например, добавьте в Ваш класс А нечто подобное
Class A
{
//bla-bla-bla
public $notStatic;
function &RetByRefFunc() {
return $this->notStatic;
}
}

А теперь потестируем Ваш Класс
$test = new A("test");
$ref = &$test->RetByRefFunc();
$ref = "modified";
var_dump($test->RetByRefFunc()); //return modified

$AString = 'StringA';
$BString = 'StringB';
$FirstClass = array( 'A', 'constructor_arguments' => array( &$AString ) );
$MultipleExtend = new MultipleExtendPattern( $FirstClass, 'B' );

$test2 = &$MultipleExtend->RetByRefFunc();
$test2 = "modified";
var_dump($MultipleExtend->RetByRefFunc()); //return NULL

Как Видите есть разница.
Действительно. Но это вовсе не "call_user_method_array и подобные функции не возвращают by ref", это проблема магического метода __call, который похоже до сих пор не исправили.

http://bugs.php.net/bug.php?id=30959
да, тут я был не прав, но Вы сами видите, что это работать не будет.
По поводу агрегации. Агрегация - это отношение часть-целое в ООП. Можете почитать Гради Бутча для более подробного разъяснения.
это когда объект какого-то класса, содержит в себе объекты других классов.
Например
class A
{
$a = 'A';
}

class B
{
$b = 'B';
}

class C
{
$a;
$b;
function __construct($str1, $str2) {
$this->a = new A($str1);
$this->b = new B($str2);
}
}
В Вашем примере вы просто упростили обращение к методам вложенных классов, не

$C->a->a а просто
$C->a

Но принцип тот же, т.к. в массиве ExtendsClasses Вы храните экземпляры объектов

И вообще если объект класса C не instanceof A, то это не наследование :-)))
Про агрегацию понял. Да, по сути то же самое, только вызовы замаскированы

Со всем остальным тоже полностью согласен. Попытка можно сказать провалилась, может потом как-нибудь возникнет задача, где этот код будет востребован :)
Собственно вот обновленный, доработанный вариант
http://www.pastebin.ca/928739
А дальнейшее наследование и protected-методы?
protected возможно и так будет работать (это же не на уровне интерпретатора наследование), надо проверить правда. А под дальнейшим наследованием что имеется ввиду?
Наследовать от этого якобы класса новый класс :)
явно не получится, все равно придется в конструкторе оформлять данные, от кого этот класс наследуется. Реализация по сути будет такой же
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации