Действительно короткая версия проще, потому что вы не можете. Так работают черты характера.
Когда вы пишете use SomeTrait;
на PHP, вы (эффективно) говорите компилятору скопировать и вставить код из Trait в класс, где он используется.
Поскольку он use SomeTrait;
находится внутри класса, он не может добавлять его implements SomeInterface
к классу, потому что он должен находиться вне класса.
"Почему в PHP нет типов Traits?"
Потому что они не могут быть созданы. На самом деле черты - это просто языковая конструкция ( указывающая компилятору скопировать и вставить код черты в этот класс), а не объект или тип, на которые может ссылаться ваш код.
Итак, я хочу «спроектировать» код, чтобы каждый класс, который хочет использовать мою черту, должен реализовывать интерфейс.
Этого можно добиться с помощью абстрактного класса для use
признака, а затем расширения классов из него.
interface SomeInterface{
public function someInterfaceFunction();
}
trait SomeTrait {
function sayHello(){
echo "Hello my secret is ".static::$secret;
}
}
abstract class AbstractClass implements SomeInterface{
use SomeTrait;
}
class TestClass extends AbstractClass {
static public $secret = 12345;
}
$test = new TestClass();
$test->sayHello();
Однако - если вам действительно нужно обеспечить, чтобы любой класс, который использует черту, имел определенный метод, я думаю, вы можете использовать черты там, где вы должны были быть абстрактными классами в первую очередь.
Или что у вас неверная логика. Вы должны требовать, чтобы классы, реализующие интерфейсы, имели определенные функции, а не то, что если у них есть определенные функции, они должны объявить себя реализующими интерфейс.
редактировать
Фактически вы можете определить абстрактные функции внутри Traits, чтобы заставить класс реализовать метод. например
trait LoggerTrait {
public function debug($message, array $context = array()) {
$this->log('debug', $message, $context);
}
abstract public function log($level, $message, array $context = array());
}
Однако это по-прежнему не позволяет реализовать интерфейс в трейте и по-прежнему пахнет плохим дизайном, поскольку интерфейсы намного лучше, чем трейты при определении контракта, который должен выполнить класс.