Итак, я, наконец, добрался до игры с чертами, и они очень удобны, проблема, с которой я столкнулся, заключается в том, что я хочу иметь некоторые черты, чтобы добавить функциональность к моим объектам данных. Само по себе это просто, за исключением того, что при этом я использую методы, определенные в моем базовом объекте данных.
abstract class Base_Object {
protected function _addToUpdate($field, $value) {
...
}
...
}
trait Extended_Object {
public function doSomeStuff() {
...
$this->_addToUpdate($someVar, $someOtherVar);
}
...
}
class User extends Base_Object {
use Extended_Object;
...
}
Моя проблема заключается в том, что если кто-то еще в моей команде решит использовать черту Extended_Object
для объекта, который не расширяет черту Base_Object
. Я думал о том, чтобы поставить галочку в методе _addToUpdate
, но в идеале я хотел бы, чтобы при создании экземпляра отображалась ошибка.
Я придумал решение, которое работает, но заставляет меня чувствовать себя немного грязным и далеким от идеала.
abstract class Base_Object {
protected function _addToUpdate($field, $value) {
...
}
...
}
trait Extended_Object {
abstract protected function _addToUpdate($field, $value);
public function doSomeStuff() {
...
$this->_addToUpdate($someVar, $someOtherVar);
}
...
}
class User extends Base_Object {
use Extended_Object;
...
}
Добавляя абстрактный метод к Extended_Object
, я могу, по крайней мере, быть уверенным, что будет отображаться ошибка, если метод, который мне нужен в Base_Object
, отсутствует, но я не могу гарантировать, что рассматриваемый метод действительно будет делать то, что я хочу.
В идеале я хотел бы иметь возможность запускать что-то вроде кода ниже, когда объект создается с использованием признака Extended_Object
if (!($this instanceof Base_Object)) {
throw new Inheritance_Exception("Base_Object");
}
Я надеюсь, что кто-то нашел способ сделать это или, по крайней мере, лучшее решение, чем мое.
Примечание: я знаю, что могу сделать это с помощью конструктора, но это будет жизнеспособно только при использовании одного трейта, если я решу позже создать еще несколько трейтов расширения объекта, это станет очень грязным очень быстро
Редактировать: я понимаю, что трейты на самом деле не предназначены для того, что я пытаюсь сделать, но они хотя бы частично позволяют мне обойти проблему одиночного наследования, и я знаю, что я не единственный разработчик, планирующий это сделать. использовать их таким образом