Example #2 from PHP manual http://php.net/manual/en/language.oop5.traits.php states
<?php
class Base {
public function sayHello() {
echo 'Hello ';
}
}
trait SayWorld {
public function sayHello() {
parent::sayHello();
echo 'World!';
}
}
class MyHelloWorld extends Base {
use SayWorld;
}
$o = new MyHelloWorld();
$o->sayHello();
?>
This is correct code, but it's not safe to use parent::
in that context. Let's say I wrote my own 'hello world' class which does not inherit any other classes:
<?php
class MyOwnHelloWorld
{
use SayWorld;
}
?>
This code will not produce any errors until I call the sayHello()
method. This is bad.
On the other hand if the trait needs to use a certain method I can write this method as abstract, and this is good as it ensures that the trait is correctly used at compile time. But this does not apply to parent classes:
<?php
trait SayWorld
{
public function sayHelloWorld()
{
$this->sayHello();
echo 'World!';
}
public abstract function sayHello(); // compile-time safety
}
So my question is: Is there a way to ensure (at compile time, not at runtime) that class which uses a certain trait will have parent::sayHello()
method?
No, there is not. In fact, this example is very bad, since the purpose of introducing traits was to introduce same functionality to many classes without relying on inheritance, and using parent
not only requires class to have parent, but also it should have specific method.
On a side note, parent
calls are not checked at the compile time, you can define simple class that does not extend anything with parent calls in it's methods, ant it will work until one of these method is called.