trait能力在PHP中的使用

分享 lys 2021-10-15 19次点击 来自 分享

lys

https://zhuanlan.zhihu.com/p/136940002

  1trait能力在PHP中的使用
  2张玥
  3张玥
  42 人赞同了该文章
  5相信大家对trait已经不陌生了,早在5.4时,trait就已经出现在了PHP的新特性中。当然,本身trait也是特性的意思,但这个特性的主要能力就是为了代码的复用。
  6
  7我们都知道,PHP是现代化的面向对象语言。为了解决C++多重继承的混乱问题,大部分语言都是单继承多接口的形式,但这也会让一些可以复用的代码必须通过组合的方式来实现,如果要用到组合,不可避免的就要实例化类或者使用静态方法,无形中增加了内存的占用。而PHP为了解决这个问题,就正式推出了trait能力。你可以把它看做是组合能力的一种变体。
  8
  9trait A
 10{
 11    public $a = 'A';
 12    public function testA()
 13    {
 14        echo 'This is ' . $this->a;
 15    }
 16}
 17
 18class classA
 19{
 20    use A;
 21}
 22class classB
 23{
 24    use A;
 25    public function __construct()
 26    {
 27        $this->a = 'B';
 28    }
 29}
 30
 31$a = new classA();
 32$b = new classB();
 33
 34$a->testA();
 35$b->testA();
 36从上述代码中,我们可以看出,trait可以给应用于任意一个类中,而且可以定义变量,非常方便。trait最需要注意的是关于同名方法的重载优先级问题。
 37
 38trait B {
 39    function test(){
 40        echo 'This is trait B!';
 41    }
 42}
 43trait C {
 44    function test(){
 45        echo 'This is trait C!';
 46    }
 47}
 48
 49class testB{
 50    use B, C;
 51    function test(){
 52        echo 'This is class testB!';
 53    }
 54}
 55
 56$b = new testB();
 57$b->test(); // This is class testB!
 58// class testC{
 59//     use B, C;
 60// }
 61
 62// $c = new testC();
 63// $c->test(); // Fatal error: Trait method test has not been applied, because there are collisions with other trait methods on testC
 64在这里,我们的类中重载了test()方法,这里输出的就是类中的方法了。如果注释掉testB类中的test()方法,则会报错。因为程序无法区分出你要使用的是哪一个trait中的test()方法。我们可以使用insteadof来指定要使用的方法调用哪一个trait。
 65
 66class testE{
 67    use B, C {
 68        B::test insteadOf C;
 69        C::test as testC;
 70    }
 71}
 72$e = new testE();
 73$e->test(); // This is trait B!
 74$e->testC(); // This is trait C!
 75当然,现实开发中还是尽量规范方法名,不要出现这种重复情况。另外,如果子类引用了trait,而父类又定义了同样的方法呢?当然还是调用父类所继承来的方法。trait的优先级是低于普通的类继承的。
 76
 77trait D{
 78    function test(){
 79        echo 'This is trait D!';
 80    }
 81}
 82
 83class parentD{
 84    function test(){
 85        echo 'This is class parentD';
 86    }
 87}
 88
 89class testD extends parentD{
 90    use D;
 91}
 92
 93$d = new testD();
 94$d->test(); // This is trait D!
 95最后,trait中也是可以定义抽象方法的。这个抽象方法是引用这个trait的类所必须实现的方法,和抽象类中的抽象方法效果一致。
 96
 97trait F{
 98    function test(){
 99        echo 'This is trait F!';
100    }
101    abstract function show();
102}
103
104class testF{
105    use F;
106    function show(){
107        echo 'This is class testF!';
108    }
109}
110$f = new testF();
111$f->test();
112$f->show();
113trait真的是PHP是非常灵活的一个功能。当然,越是灵活的东西越需要我们去弄明白它的一些使用规则,这样才能避免一些不可预见的错误。
目前暂无回复

©2020 Powered by 闽ICP备17030771号-1