PHP Trait

PHP5.4实现了一种代码复用的方法称为Trait。Trait为了减少单继承语言的限制,能够自由地在不同层次结构内独立的类中复用方法,Trait和Class组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。无法通过 trait 自身来实例化。一个类要应用trait需要使用use关键字,一个类可以应用多个trait,只需要在use关键字后用逗号分隔多个trait。trait中也可以应用其他的trait。

<?php
trait a{
    function getA(){
        return "a";
    }
}
trait b{
    function getB(){
        return "b";
    }
}
class Test{
    use a,b;
}
$test=new Test();
echo $test->getA()."\n";
echo $test->getB()."\n";

trait c{
    use a,b;
}
class Test2{
    use c;
}
$test=new Test2();
echo $test->getA()."\n";
echo $test->getB()."\n";
?>

如果trait和class中存在相同的成员,则优先级规则为,当前类的成员->trait的成员->继承的成员。

<?php
trait a{
    function getA(){
        parent::getA();
        echo "a in trait\n";
    }
}
class Base{
    function getA(){
        echo "a in Base\n";
    }
}
class Test extends Base{
    use a;
}
class Test2 extends Base{
    use a;
    function getA(){
        echo "a in Test2\n";
    }
}
$test=new Test();
$test->getA();

$test2=new Test2();
$test2->getA();
?>

在应用多个trait时,如果插入了同名的方法,则需要解决冲突,否则会产生致命错误。解决冲突可以使用insteadof关键字来指明使用哪一个方法。还可以通过as关键字为某个方法引入别名,as关键字还可以调整方法的访问控制。

<?php
trait A {
    public function printLower() {
        echo 'a';
    }
    public function printUpper() {
        echo 'A';
    }
}

trait B {
    public function printLower() {
        echo 'b';
    }
    public function printUpper() {
        echo 'B';
    }
    public function testAccess(){
        
    }
}

class Test {
    use A, B {
        B::printLower insteadof A;
        A::printUpper insteadof B;
        B::printUpper as private upper;
        testAccess as protected;
    }
}

$test=new Test();
$test->printLower();
$test->printUpper();
//$test->upper();
//$test->testAccess();
?>

trait还支持抽象方法,应用trait的类需要实现抽象方法,否则会产生致命错误。trait还支持静态成员。

<?php
trait a{
    function lower(){
        return "a";
    }
    abstract function upper();
    public static function foo(){
        echo "static function foo\n";
    }
}
class Test{
    use a;
    function upper(){
        return "A";
    }
}
$t=new Test();
echo $t->lower()."\n";
echo $t->upper()."\n";
Test::foo();
?>

trait中可以定义属性,但是应用trait的类不能定义与之同名的属性,否则会产生致命错误,除非属性是兼容的,即访问控制和初始默认值都相同。PHP7.0之前即使属性兼容也会有E_STRICT的提醒。

<?php
trait a{
    public $var="a";
    public $diff1="a";
    public $diff2="a";
}
class Test{
    use a;
    public $var="a";
    //public $diff1="b";
    //protected $diff2="a";
}
?>

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值