trait是php5.4以后新增加的一个功能,可以将多个类中,共用的一些属性和方法提取出来做来公共trait类。 trait可能大家用的不是很多,这篇文章会举出几个例子来理解如何使用trait;然后对于这个特性,由于笔者在自己的框架中有用到,也会指出具体使用场景。
介绍
php从以前到现在一直都是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php出了Trait这个特性。
通过在类中使用use关键字,声明要组合的trait名称。
具体的trait声明则使用trait
关键字,trait不能被实例化。
例子
话不多说,接下来举几个例子来理解。
基本使用实例:
trait Dog
{
public $name = 'dog';
public function talk()
{
echo 'dog talk<br>';
}
}
class Animal
{
public function eat()
{
echo 'animal eat<br>';
}
}
class Cat extends Animal
{
use Dog;
public function jump()
{
echo 'cat jump<br>';
}
}
$cat = new Cat();
$cat->talk();
$cat->eat();
$cat->jump();
以上会输出:
可以发现,在cat
类中use引入trait后,能够使用trait中的方法。
trait、父类和本类存在同名方法实例:
trait Dog
{
public $name = 'dog';
public function talk()
{
echo 'dog talk<br>';
}
public function eat()
{
echo 'dog eat<br>';
}
}
class Animal
{
public function talk()
{
echo 'animal talk<br>';
}
public function eat()
{
echo 'animal eat<br>';
}
}
class Cat extends Animal
{
use Dog;
public function talk()
{
echo 'cat talk<br>';
}
}
$cat = new Cat();
$cat->talk();
$cat->eat();
以上会输出:
由此可见,trait会覆盖父类中的同名方法,而本来会覆盖trait中的同名方法。
注意,如果在类中use了某个trait,那么在此类中,不能重复定义trait中的属性不相同的值。 在上面的代码中,如果cat类定义了$name属性,那么只能定义为’dog’,否则会报错。
组合多个trait实例:
trait trait1
{
public function talk()
{
echo 'trait1 talk<br>';
}
public function eat()
{
echo 'trait1 eat<br>';
}
}
trait trait2
{
public function talk()
{
echo 'trait2 talk<br>';
}
public function eat()
{
echo 'trait2 eat<br>';
}
}
class Cat
{
use trait1,trait2{
trait1::talk insteadof trait2;
trait1::eat insteadof trait2;
}
}
class Dog
{
use trait1,trait2{
trait1::talk insteadof trait2;
trait1::eat insteadof trait2;
trait2::talk as talken;
trait2::eat as eaten;
}
}
$cat = new Cat();
$cat->talk();
$cat->eat();
echo '<br>';
$dog = new Dog();
$dog->talk();
$dog->eat();
$dog->talken();
$dog->eaten();
以上会输出:
使用场景
trait可以定义多个类的公共方法,在类中use特定的trait后,当实例化某个类时,能够调用trait中的同名方法。 也就是说,可以把多个类中相同的方法放在trait中,作为公共方法。
以下是实例化某个类时,调用trait中公共方法的例子:
trait trait1
{
public function __construct($config = [])
{
if (!empty($config)) {
foreach ($config as $key => $row) {
$this->$key = $row;
}
}
$this->init();
}
public function init()
{
}
}
class demo
{
use trait1;
public $name;
public function init()
{
echo 'demo init';
}
}
$demo = new demo(['name'=>'test_name']);
echo '<br>';
echo $demo->name;
以上会输出:
这种方式在框架中会用得比较多,特别是组件设计模式,只要在定义组件的类中引用组件trait,那么在初始化的时候,就会把组件的配置加载进去。
总结
以上就是trait的大概用法,在某些场合,使用trait会方便实现PHP无法多继承的问题。