Я могу расширить класс с помощью больше чем 1 класса в PHP?

139
задан T Zengerink 9 July 2012 в 17:59
поделиться

8 ответов

Ответ на Ваше редактирование:

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

Это ужасно, хотя это работает с точки зрения пользователя класса A:

class B {
    public function method_from_b($s) {
        echo $s;
    }
}

class C {
    public function method_from_c($s) {
        echo $s;
    }
}

class A extends B
{
  private $c;

  public function __construct()
  {
    $this->c = new C;
  }

  // fake "extends C" using magic function
  public function __call($method, $args)
  {
    $this->c->$method($args[0]);
  }
}


$a = new A;
$a->method_from_b("abc");
$a->method_from_c("def");

"abcdef"

Печати
162
ответ дан 23 November 2019 в 23:17
поделиться

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

0
ответ дан 23 November 2019 в 23:17
поделиться

PHP еще не поддерживает несколько наследование классов, он действительно однако поддерживает, несколько соединяют интерфейсом с наследованием.

См. http://www.hudzilla.org/php/6_17_0.php для некоторых примеров.

0
ответ дан 23 November 2019 в 23:17
поделиться

PHP не позволяет множественное наследование, но можно сделать с реализацией нескольких интерфейсов. Если реализация "тяжела", обеспечьте скелетная реализация для каждого интерфейса в отдельном классе. Затем Вы можете делегат весь интерфейсный класс к этим скелетным реализациям через объектное включение .

0
ответ дан 23 November 2019 в 23:17
поделиться

Существуют планы относительно добавления соединения-ins скоро, я верю.

, Но до тех пор, пойдите с принятым ответом. Можно абстрагировать это немного для создания "растяжимого" класса:

class Extendable{
  private $extender=array();

  public function addExtender(Extender $obj){
    $this->extenders[] = $obj;
    $obj->setExtendee($this);
  }

  public function __call($name, $params){
    foreach($this->extenders as $extender){
       //do reflection to see if extender has this method with this argument count
       if (method_exists($extender, $name)){
          return call_user_func_array(array($extender, $name), $params);
       }
    }
  }
}


$foo = new Extendable();
$foo->addExtender(new OtherClass());
$foo->other_class_method();

Примечание, которое в этой модели "OtherClass" добирается для 'знания' о $foo. OtherClass должен иметь государственную функцию, вызванную "setExtendee" для установки этих отношений. Затем если это - методы, вызываются от $foo, это может получить доступ к $foo внутренне. Это, однако, не доберется, доступ к любым частным/защищенным методам/переменным как реальный расширенный класс был бы.

14
ответ дан 23 November 2019 в 23:17
поделиться

Я прочитал несколько статей обескураживающее наследование в проектах (в противоположность библиотекам/платформам), и призывающий к программе против интерфейсов, нет против реализаций.
Они также защищают OO составом: при необходимости в функциях в классе a и b сделайте c наличием участников/полей этого типа:

class C
{
    private $a, $b;

    public function __construct($x, $y)
    {
        $this->a = new A(42, $x);
        $this->b = new B($y);
    }

    protected function DoSomething()
    {
        $this->a->Act();
        $this->b->Do();
    }
}
6
ответ дан 23 November 2019 в 23:17
поделиться

Классы не предназначены, чтобы быть просто наборами методов. Класс, как предполагается, представляет абстрактное понятие, и с состоянием (поля) и с поведением (методы), который изменяет состояние. Используя наследование только для получения некоторого желаемого поведения походит на плохой дизайн OO и точно причину, почему много языков запрещают множественное наследование: для предотвращения "наследования спагетти", т.е. расширения 3 классов, потому что у каждого есть метод, в котором Вы нуждаетесь, и окончание с классом, который наследовал 100 методов и 20 полей, все же только когда-либо использует 5 из них.

17
ответ дан 23 November 2019 в 23:17
поделиться

У Вас не может быть класса, который расширяет два базовых класса. Вы не могли иметь.

// this is NOT allowed (for all you google speeders)
Matron extends Nurse, HumanEntity

у Вас могла однако быть иерархия следующим образом...

Matron extends Nurse    
Consultant extends Doctor

Nurse extends HumanEntity
Doctor extends HumanEntity

HumanEntity extends DatabaseTable
DatabaseTable extends AbstractTable

и так далее.

133
ответ дан 23 November 2019 в 23:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: