Pull to refresh

Comments 58

Есть ли жизнь на марсе?
Есть ли множественное наследование в PHP? :)))
Не знаю насчёт жизни на Марсе, но противоречия между первым пунктом и последующими нет никакого, уж извините.

class A {
  public function m_A() {
    echo "This is A!\n";
  }
}
class B {
  public function m_B() {
    echo "This is B!\n";
  }
}
class C {
  private $_parent_A;
  private $_parent_B;
  public function __construct() {
    $this->_parent_A = new A();
    $this->_parent_B = new B();
  }
  public function __call($m, $a) {
    try {
      $method_A = new ReflectionMethod('A', $m);
      return $method_A->invokeArgs($this->_parent_A, $a);
    } catch (ReflectionException $e) {
      $method_B = new ReflectionMethod('B', $m);
      return $method_B->invokeArgs($this->_parent_B $a);
    }
  }
}
$C = new C();
$C->m_A();
$C->m_B();

Часто использовать не рекомендуется так как небыстро это, но если приспичит... почему бы и нет?

P.S. Как при этом организовать правильное перекрытие методов - хороший вопрос для собеседования...
Понял, что имелось ввиду.
Жаль нельзя переголосовать.. отвратительно выглядит и не представляю ситуацию, когда нужно множественное наследование в пхп.
Ужасы нашего городка :) А чем оно лучше классики?

class A {
public function m_A() {
echo "This is A!\n";
}
}
class B {
public function m_B() {
echo "This is B!\n";
}
}

class C extends A {
private $b;
public function m_B()
{
if (!isset($this->b)) {
$this->b = new B();
}
return $b->m_B()
}
}

$C = new C();
$C->m_A();
$C->m_B();
Естественно это никакое не множественное наследование...
Да? А чем это отличается от множественного наследования в C++? С точки зрения человека, использующего класс? Это если про мою версию говорить. Ваша - да, это не наследование.
Отличается как небо и земля. Возможно, интерфейсы те же, то ТИПЫ ДРУГИЕ!

Ваш класс C не унаследован ни от А, ни от B, хотя имеет интерфейсы (и даже их реализацию) от обоих этих классов. Но он не унаследован ни от одного из них, поэтому не влезет ни в одну из этих конструкций:

public function useA(A $a).........
public function useB(B $b).........
if ($object instanceof A).........
Типы и интерфейсы:

interface A_Interface { public mA(); }
interface B_Interface { public mB(); }
class A implements A_Interface {.........
class B implements B_Interface {.........
class C extends A implements A_interface, B_Interface {.....

Класс С унаследовал типы, все нормально и с типами и с интерфейсами:

public function useA(A_Interface $a)....
public function useB(B_Interface $b)....
public function useC(C $c)....
if ($object instanceof A_Interface)...
if ($object instanceof B_Interface)...

Здесь наследование C от A на практике упрощает реализацию интерфейса A_Interface, интерфейс B_Interface все равно реализовать придется, возможно с помощью копипаста.

Плохо, что в PHP нет множественного наследования ^_^
Хм. Зачем реализовывать B_Interface с помощью копипаста? Отсылка через __call уж тут-то сработает на ура.
Последняя конструкция - это просто известный антипаттерн (хотя иногда и неизбежный), первые две к ООП тоже не имеют отношения. Да, полноценное множественное наследование поддерживающее все средства языка может быть реализовано только средствами самого языка, но поддержка "трёх китов" (наследование, инкапсуляция, полиморфизм) в сочетании с множественным наследованием в PHP делается на ура.
Ну если вы находите ваш подход приемлемым решением - не буду спорить, все сущее бренно...
Но я бы не хотел никогда встречаться с таким креативом в реальных больших проектах :)
То, что вы привели - это не множественное наследование, это агрегация. Класс C наследует не все методы класса B, а только избранные. То, что вы один из классов унаследовали прямо - вообще к теме множественного наследования имеет косвенное отношение, это просто оптимизация, не более того.
Можно подумать, ваш пример - множественное наследование ;)
То, что я привел - это классический концепт, повсеместно применяемый на практике, а вот назначение вашего примера я вообще не понял :(
у вас декоратор тут а не наследование
Множественное наследование и эмуляция оного - разные вещи.
Кто бы спорил. Но если мы говорим об использовании множественного наследования, то его наличие в языке отнюдь не критично... Можно ведь использовать классы, объекты, наследование и прочее в C - так куча библиотек сделана и никто не удивляется...
Так можно сделать набор объектов "контекст" и грамотной работой с ними реализовать в PHP замыкания :)
для интерфейсов - есть (-:
правда это сомнительное преимущество, которое стоит использовать с крайней аккуратностью и точно зная почему это стало необходимо, ибо за довольно редкими и очевидными исключениями, если класс имплементирует сразу пачку интерфейсов, то это обычно сигнализирует о нарушении single responsibility principle ( http://en.wikipedia.org/wiki/Single_responsibility_principle )
UFO just landed and posted this here
Вам шашечки или ехать? Множественного наследования нет, но если есть желание, то поиспользовать его можно...
UFO just landed and posted this here
Наверное правильно было бы написать: «Используете ли вы множественную имплементацию интерфейсов в PHP?». Тогда небыло бы лишних вариантов. Хотя с другой стороны вопрос на засыпку, так сказать :).
Не дай бог такой вопрос в (автоматизированном) тесте попадется - то ли "вопрос на засыпку", то ли ляп составителя.
Его на хабре не часто увидишь, в отличие от НЛО )))
Э. Не стоит путать! НЛО един, а Ктулху своим множественным наследованием жрёт мозг. И устраивает человеческие жертвоприношения!
пишет ли НЛО на PHP?
Где вариант ответа "а что это за птица такая", а?
Так интерфейсов (это не наследование) или множественное наследование (несуществующее в PHP)?
Множественное наследование интерфейсов.
implements - придумали в PHP. В C++ нет интерфейсов, а есть абстрактные классы, которые _наследуются_.

Поэтому я думаю, что говорить "множественное наследование интерфейсов" - правильно
"implements - придумали в PHP" - да ну что ты?

а как ты назовёш следуюшее:

class myFormField implements ArrayAccess, Iterator, Countable { } ???
Да это PHP. Можеш проверить... и я бы хотел услышать как ты это назовёш? ;)

class myFormField implements ArrayAccess, Iterator, Countable {

public function offsetExists($name) {}
public function offsetGet($name) {}
public function offsetSet($offset, $value) {}
public function offsetUnset($offset) {}
public function rewind() {}
public function key() {}
public function current() {}
public function next() {}
public function valid() {}
public function count() {}
}
Это называется реализацией интерфейса.
Хотя не совсем понимаю, что обсуждаем...
это можно назвать множественным наследованием интерфейсов, а можно еще как-нибудь ))
Именно так это и называетса. В PHP нету множественного наследования классов, всмысле родной потдержки нету - эмулировать можно, зато есть множественное наследоваение интэрфэйсов.
ага, это видно из названия опроса ^_^
Зато не видно в вариантах ответа o_O
я вот прочитав опрос все понял сразу.
Терминология - скользкая тема )
Просто (я не силён ни в чём) обязательная самостоятельная реализация всего, что есть в родителе, и наследование - как-то не вяжутся...
Да, терминология - это для филологов )
Наследуются именно _интерфейсы_.
Еще раз скажу - в C++ нет интерфейсов, они описываются в абстрактных классах, от которые можно наследовать. Так что не думаю, что это совсем уж неправильно
implements придумали в Java, не надо. =)
Это википедия так сказала? )
implements придумали предки Шекспира! ;)
P.S. Раз уж сегодня первое апреля, то почему не напиться? ))
Мда... Как я мог о них забыть?.. =)
Точно, давайте напьемся, друзья! :)
(моя поехал в кабак:)
>implements - придумали в PHP
Пацталом. А что ещё "придумали в пхп"?
Кстати, а что-нибудь _вообще_ придумали в пхп? Хорошего, конечно, всякого бреда-то там навалом.
Не совсем понятем вопрос. Что такое множественное наследование интерфейсов? Если подразумевается имлементация классом нескольких интерфейсов, то использую конечно, очень помогает для написания моделей.
А множественное наследование как факт (Class A{} Class B extends A {} Class C extends B {} ) для имплементации невозможно.
Такого количества НЛО давно уже не видел... Походу, процентов сорок лежат в танке и спят)))
да, использую, особенно когда в команде работаю с 2-мя и более программистами, при помощи интерфейсов очень просто стандартизировать поведение. Ну например (вымышленный) сделай мне шаблонизатор который реализует интерфейс
implements Templater{
public function assign($name, $value);
}

ну или есть у вас в системе Observer, вам скармливают объект-слушающий, а у вас стандартизирован вызов:
Observer::add = public function(ObserverClient $obj);

в основном в таком контексте: тоесть для формализации ТЗ и интерфейса доступа.
ну или есть у вас в системе Observer, вам скармливают объект-слушающий, а у вас стандартизирован вызов:
Observer::add = public function(ObserverClient $obj);


Да, в такой системе без использования интерфейсов все размывается и разваливается. Особенно если классов ObserverClient очень много.
пожалуй нужно пояснить почему тут не обойтись просто наследованием от абстрактного класса. Рассмотрим задачку кеширования: например у нас есть Observer который следит за состоянием кеша (задачи прегенерации, задачи логирования и т.д.) и много маленьких разнопрофильных клиентов. Кто-то из клиентов, например, меняет состояние кеша и просит обсервер всех уведомить, что кеш нужно сбросить.
Понятно, что все клиенты отвечают за разные части системы и потому держать в основании дерева их классов ObserverClient не целесообразно.
А так например у нас есть готовый модуль (class A) и мы говорим: теперь эта сущность (наш модуль) тоже научилась работать c нашим сервером кеша (class ACached extends A implements CacheClient)

простите, что примеры немного искуственными кажутся, просто полностью раскрывать задачи занятие не для часу ночи.

Но суть такова: интерфейсы необходимы для стандартизации, а ее нельзя достичь простым наследованием т.к. объекты по своей природе не наследуются от одного родителя (например разнопрофильные сторониие библиотеки).
а вообще автору спасибо за топик. Мало где обсужается что-то действительно полезное, в основном обсасываются общеизвестные вещи
Можно назвать примеси множественным наследованием. До 5.4 есть костыли, а в 5.4 вроде решили проблемку.
Sign up to leave a comment.

Articles