PHP中的trait

原创 maolego 2022年05月26日 150 2

一、Trait是什么

trait php5.4以后新增加的一个功能,可以将多个类中,共用的一些属性和方法提取出来做来公共trait类,

传统的PHP类是单一继承模式,即每个类只能继承一个父类。

Trait类的出现让PHP类可以继承多个“父类”。

 

二-、Trait使用

简单地讲,Trait就是一种不同于继承的语法,定义一个Trait类,在其他类中使用它则是采用use关键字,有点类似于命名空间的用法,但是含义不同。use关键字在一个类中引入Trait类后,相当于 require include了一段代码进来,不同之处在于useTrait类与当前类是可以看做同一个类的,即当前类可以用$this关键字调用Trait类的方法

<?php
//创建triat类MytestOne
trait MytestOne{
    public function a(){
        return '创建triat类MytestOne';
    }
}

//创建triat类MytestTwo
trait MytestTwo{
    public function b(){
        return '创建triat类MytestTwo';
    }
}

//创建Demo1类
class Demo{
    use MytestOne,MytestTwo;  //引入Trait类
    public function index(){
        return 'hello world';
    }
}

$obj = new Demo;

echo $obj->a(); // 访问MytestOne类a()
echo "<br/>";
echo $obj->b(); // 访问MytestTwo类 b()
echo "<br/>";
echo $obj->index();

代码输出:

创建triat类MytestOne
创建triat类MytestTwo
hello world

 

三、Trait冲突

在PHP中,如果当前类use了两个Trait类,同时两个trait类都存在一个同名的方法,此时如果没有明确解决冲突将会产生一个致命错误。

为了解决多个 trait 在同一个类中的命名冲突,需要使用 insteadof 操作符来明确指定使用冲突方法中的哪一个。as 操作符可以 为某个方法引入别名。 注意,as 操作符不会对方法进行重命名,也不会影响其方法

<?php
trait A {
    public function begins(){
        echo "a";
    }
    public function ends(){
        echo "A";
    }
}

trait B {
    public function begins(){
        echo "b";
    }
    public function ends(){
        echo "B";
    }
}

class demo {
    use A,B{
        A::begins insteadof B; // begins方法冲突时使用A类的begins方法而不使用B类的begins方法
        B::ends insteadof A;  // begins方法冲突时使用B类的ends方法而不使用A类的ends方法
        
        A::ends as a;  //声明A类的ends方法为a,作用于该类
    }
}
$obj = new demo();

$obj->begins();  // a
echo "<br/>";
$obj->ends();  // B
echo "<br/>";
$obj->a(); // A

insteadof: 通过该关键字指定方法名冲突时该使用哪个Trait类的方法

as : 通过as关键字将同名方法指定为一个别名,仅作用于当前类

四、Trait优先级

从基类继承的成员会被 trait 插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了 trait 的方法,而 trait 则覆盖了被继承的方法。

优先级:自身方法 > trait的方法 > 继承的方法

 

<?php
trait A {
    public function begins(){
        echo "hello";
    }
    public function ends(){
        echo 'AAA';
    }
}

class B{
    public function ends(){
        echo 'BBB';
    }
}

class demo extends B {
    use A;
    public function begins(){
        echo "world";
    }
}
$obj = new demo();
// 自身类 中 begins() 覆盖 trait 中的 begins() 方法;
$obj->begins();  // world  
echo '<br/>';
// trait 中的 ends() 方法 覆盖 B类中的 ends() 方法;
$obj->ends(); // AAA

代码输出:

world
AAA

 

PHP 手册 : https://www.php.net/manual/zh/language.oop5.traits.php

本文地址: https://maolego.com/400.html
温馨提示: 本站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议
相关文章 关键词:

发表回复

*

  1. tx
    admin 1楼 2022年09月08日

    博主,交换友情链接吗?

    • tx
      maolego 2楼 2022年10月28日

      大哥,加你QQ了,发你邮箱信息了