在阅读laravel文档的时候看到一个类 是以 Trait声明的。平时在工作中从来没有用过,于是就去看了下官方文档。原来这个类早在php5.4.0
就有了。可惜在项目中从来没有用过。
Trait看上去既像类又像接口,其实都不是,Trait可以看做类的部分实现,可以混入一个或多个现有的PHP类中,其作用有两个:表明类可以做什么;提供模块化实现。Trait是一种代码复用技术,为PHP的单继承限制提供了一套灵活的代码复用机制。
为什么使用Trait
PHP语言使用一种典型的单继承模型,在这种模型中,我们先编写一个通用的根类,实现基本的功能,然后扩展这个根类,创建更具体的子类,直接从父类继承实现。这叫做继承层次结构,很多编程语言都使用这个模式。大多数时候这种典型的继承模型能够良好运作,但是如果想让两个无关的PHP类具有类似的行为,应该怎么做呢?
Trait就是为了解决这种问题而诞生的。Trait能够把模块化的实现方式注入多个无关的类中,从而提高代码复用。
下面看几个简单的例子
简单使用
trait Member
{
public function info()
{
echo 'this is trait';
}
}
class ShowMember
{
use Member;
}
$Member = new ShowMember();
$Member->info();
以上代码会输出this is trait
,从这里可以看出Trait的使用方法很简单,即使用use关键字。可能你已经注意到,命名空间和Trait使用的都是use关键字,不同之处在于导入位置,命名空间在类的定义体外导入,而Trait在类的定义体内导入。
优先级
当一个类继承的基类,跟使用的Trait有相同的函数名称时,应该是哪一个优先呢,下面我们来看一看。
trait Member
{
public function info()
{
echo 'this is trait';
}
}
class BaseMember
{
public function info()
{
echo 'this is base';
}
}
class ShowMember extends BaseMember
{
use Member;
}
$Member = new ShowMember();
$Member->info();
以上代码会输出this is trait
。可以看出,当继承的基类与Trait有相同的函数时,Trait的优先级是比基类要高的。下面把Trait的代码做一个修改
trait Member
{
public function info()
{
parent::info();
echo 'this is trait';
}
}
class BaseMember
{
public function info()
{
echo 'this is base';
}
}
class ShowMember extends BaseMember
{
use Member;
}
$Member = new ShowMember();
$Member->info();
以上代码会输出this is basethis is trait
。同样可以看出Trait的优先级比基类要高,并且可以再Trait中继承基类的函数。下面再把代码做一个修改。
trait Member
{
public function info()
{
echo 'this is trait';
}
}
class BaseMember
{
public function info()
{
echo 'this is base';
}
}
class ShowMember extends BaseMember
{
use Member;
public function info()
{
echo 'this is show';
}
}
$Member = new ShowMember();
$Member->info();
以上代码会输出this is show
。可以看出优先级的顺序为,当前类的优先级》Trait》基类。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。