在阅读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》基类。


旧梦发癫
678 声望76 粉丝

PHP、Golang