あなたができないので、本当に短いバージョンはより簡単です。それはTraitsの仕組みではありません。
PHP で記述use SomeTrait;
する場合、(効果的に) コンパイラに、コードを 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;
//function someInterfaceFunction(){
//Trying to instantiate this class without this function uncommented will throw an error
//Fatal error: Class TestClass contains 1 abstract method and must therefore be
//declared abstract or implement the remaining methods (SomeInterface::doSomething)
//}
}
$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());
}
ただし、これでもトレイトにインターフェイスを実装することはできず、クラスが満たす必要があるコントラクトを定義する際にインターフェイスがトレイトよりもはるかに優れているため、依然として悪い設計のような匂いがします。