PHP5新特性 trait

    trait是PHP5.4.0中引入的新概念,既像接口又像类。trait是类的部分实现(即常量、属性和方法),可以混入一个或多个现有的PHP类中。trait有两个作用:表明类可以做什么(像接口);提供模块化实现(像是类)。

    为什么要使用trait,书中举了一个例子比较形象。首先PHP使用的是一种典型的继承模型,在这种模型中通常是先编写一个通用的根类,实现基本的功能,然后扩展这个根类,创建更具体的类,直接父类继承实现。大多数情况下都能工作的很好,但是如果想让两个无关的PHP类具有类似的行为,就出现问题了。例如,RetailStore和Car两个PHP类都能使用地理编码技术把地址字符串转换为经纬度。

    第一个方案,创建一个父类Geocodable,让RetailStore和Car都继承这个类。能解决问题,但是强制让两个无关的类继承同一个父类,很不好。

    第二个方案,创建一个Geocodable接口,定义实现地理编码功能需要的方法,然后让RetailStore和Car都实现这个接口。这种解决方法好,因为每个类都能保有自然的继承层次结构。但是,要在两个类中重复实现相同的地理编码功能,这不符合DRY原则。

    第三个方案就是利用trait了,创建一个Geocodabletrait,定义并实现地理编码相关的方法,然后把在RetailStore和Car两个类中混入这个trait。这么做不会搅乱这两个类原本自然的继承层次结构。


    创建trait,就是利用trait关键字,内部的实现跟类差不多。

// 定义trait
trait TraitTest {
    protected $var;
    
    public function setVar($value) {
        $this->var = $value;
    }
    
    public function getVar() {
        if(isset($this->var) === false) {
            return false;
        }
        return $this->var;
    }
}

    使用trait的时候就是利用use关键字,将trait插入到类中,然后其他实例化和调用跟普通类一样。

class ClassTest {
    // 使用trait
    use TraitTest;
    // 类的定义...
}

$classTest = new ClassTest();
$classTest->setVar(1111);
echo $classTest->getVar();

    一个类可以插入多个trait,但是当插入的不同的trait的常量、属性或方法发生冲突时,就会报错。可以利用insteadof或as解决冲突

trait TraitTest2 {
    public function func() {
        echo 'function2';
    }
}

trait TraitTest3 {
    public function func() {
        echo 'function3';
    }
}

class ClassTest {
    // 发生冲突时, 可以利用 insteadof 解决冲突;
    use TraitTest2, TraitTest3 {
        TraitTest2::func insteadof TraitTest3;
    }
}

$classTest = new ClassTest();
// 输出为function2
$classTest->func();


还有一个很重要的点就是,从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。

此外插入了trait的类同样可以继承,继承的时候会连插入的trait一同继承。

class ChildClass extends ClassTest {
    
}

$childClass = new ChildClass();
$childClass->setVar(2222);      // 输出2222
echo $childClass->getVar();

更多详细的的trait内容可以看 官方文档 。


总的来说感觉Trait更像是一个语法糖,而且有一点很不好的地方就是在trait中可以调用类中的成员,在语法上并没有约束,只能通过文档进行约束。如果调用的成员不存在的话,就出错了。


欢迎访问我的个人博客

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值