структура — Решение множественного наследования в PHP без композиции

Я работаю над веб-приложением с Yii2 и PHP и сталкиваюсь с типичной ситуацией множественного наследования.

У меня есть занятия A а также B продлить Yii2 ActiveRecord класс, так как они представляют реляционные данные, хранящиеся в БД. Но тогда у меня есть класс C, который не расширяется (и не должен) ActiveRecord но разделяет общее поведение и переменные-члены с A а также B, Другими словами, три класса искренне имеют общие отношения «есть» с сущностью реального мира, но только A а также B хранятся в БД.

До сих пор у меня все получалось, используя черты:

abstract class AbstractMotherClass extends ActiveRecord {
use MyTrait;
}

class A extends AbstractMotherClass {}

class B extends AbstractMotherClass {}

class C {
use MyTrait;
}

trait MyTrait {
public $someVariableInherentToAllThreeClasses;

public function someMethodInherentToAllThreeClasses() {
// do something
}
}

Тогда у меня есть метод, который может принять любой из трех классов (A, B или же C) и работать с ним. До сих пор мне оставалось только бросить A или же B на это, так что я просто написал

public fonction someMethod(AbstractMotherClass $entity) {}

чтобы я мог получить подсказки типа и другие вещи в моей IDE. Но теперь я должен пройти C а также приложение вылетает, так как метод не получает ожидаемого AbstractMotherClass экземпляр, если я позвоню someMethod(new C());, Чтобы решить это, мне нужен общий класс, который все A, B, А ТАКЖЕ C может расширяться, чтобы я мог напечатать подсказку этого класса в моем методе. Но это было бы множественное наследование, так как A а также B должен также продлить ActiveRecord но C не может.

Я обнаружил множество проблем множественного наследования, но все они были решены путем изменения структуры объекта, разделения обязанностей, использования композиции вместо наследования и так далее. Мне не удалось применить эти решения здесь, потому что они не казались ни подходящими, ни практичными, но я могу ошибаться.

Каков был бы лучший способ сделать это?

Также, если у кого-то есть лучшее предложение для заголовка, я был бы рад изменить его (я не смог найти хорошего).

0

Решение

Как отметил и Грег Шмидт, вы можете использовать интерфейсы

class ActiveRecord {

}

interface SameInterface {
public function someMethodInherentToAllThreeClasses();
}

abstract class AbstractMotherClass extends ActiveRecord implements SameInterface{
use MyTrait;
}

class A extends AbstractMotherClass {}

class B extends AbstractMotherClass {}

class C implements SameInterface{
use MyTrait;
}

trait MyTrait {
public $someVariableInherentToAllThreeClasses;

public function someMethodInherentToAllThreeClasses() {
return 'bar';
}
}

function foo(SameInterface $o) {
return $o->someMethodInherentToAllThreeClasses().PHP_EOL;
}

echo foo(new C());

Конечно, вы должны скопировать и вставить в интерфейс someMethodInherentToAllThreeClasses. Интерфейсы обычно используются для решения некоторой проблемы множественного наследования.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]