首页后端开发PHPPHP中Trait的用法及示例

PHP中Trait的用法及示例

时间2024-02-02 02:05:02发布访客分类PHP浏览682
导读:收集整理的这篇文章主要介绍了PHP中Trait的用法及示例,觉得挺不错的,现在分享给大家,也给大家做个参考。PHP是单继承的语言,在PHP 5.4 traits出现之前,PHP的类无法同时从两个基类继承属性或方法,为了解决这个问题,php出...
收集整理的这篇文章主要介绍了PHP中Trait的用法及示例,觉得挺不错的,现在分享给大家,也给大家做个参考。

PHP是单继承的语言,在PHP 5.4 traits出现之前,PHP的类无法同时从两个基类继承属性或方法,为了解决这个问题,php出了Trait这个特性。(TraITs和Go语言的组合功能有点类似)

用法:通过在类中使用use关键字声明要组合的Trait名称,而具体某个Trait的声明使用trait关键词,Trait不能直接实例化。

?phptrait Drive {
        public $carName = 'BMW';
    public function driving() {
        echo "driving {
    $this->
carName}
    \n";
    }
}
 class PErson {
    public function age() {
            echo "i am 18 years old\n";
    }
}
 class Student extends Person {
        use Drive;
    public function study() {
            echo "Learn to drive \n";
    }
}
     $student = new Student();
    $student->
    study();
      //输出:Learn to drive $student->
    age();
        //输出:i am 18 years old$student->
    driving();
    //输出:driving BMW

结论:

Student类通过继承Person,有了age方法

通过组合Drive,有了driving方法和属性carName。

如果Trait、基类和本类中都存在某个同名的属性或者方法,最终会保留哪一个呢?通过下面的代码测试一下:

?php trait Drive {
    public function hello() {
            echo "hello 周伯通\n";
    }
    public function driving() {
            echo "周伯通不会开车\n";
    }
}
 class Person {
    public function hello() {
            echo "hello 大家好\n";
    }
    public function driving() {
            echo "大家都会开车\n";
    }
}
 class Student extends Person {
        use Drive;
//trait 的方法覆盖了基类Person中的方法,所以Person中的hello 和driving被覆盖    public function hello() {
            echo "hello 新学员\n";
//当方法或属性同名时,当前类中的方法会覆盖 trait的 方法,所以此处hello会覆盖trait中的        hello    }
}
     $student = new Student();
    $student->
    hello();
        //输出:hello 新学员$student->
    driving();
      //输出:周伯通不会开车

结论:当方法或属性同名时,当前类中的方法会覆盖 trait的 方法,而 trait 的方法又覆盖了基类中的方法。

如果要组合多个Trait,通过逗号分隔 Trait名称:

use Trait1, Trait2;

如果多个Trait中包含同名方法或者属性时,会怎样呢?答案是当组合的多个Trait包含同名属性或者方法时,需要明确声明解决冲突,否则会产生一个致命错误。

?phptrait Trait1 {
    public function hello() {
            echo "Trait1::hello\n";
    }
    public function hi() {
            echo "Trait1::hi\n";
    }
}
 trait Trait2 {
    public function hello() {
            echo "Trait2::hello\n";
    }
    public function hi() {
            echo "Trait2::hi\n";
    }
}
 class Class1 {
         use Trait1, Trait2;
}
     //输出:Fatal error:  Trait method hello has not been applied, because there are collisions with other trait methods on Class1 in

使用insteadof和as操作符来解决冲突,insteadof是使用某个方法替代另一个,而as是给方法取一个别名,具体用法请看代码:

?phptrait Trait1 {
    public function hello() {
            echo "Trait1::hello \n";
    }
    public function hi() {
            echo "Trait1::hi \n";
    }
}
trait Trait2 {
    public function hello() {
            echo "Trait2::hello\n";
    }
    public function hi() {
            echo "Trait2::hi\n";
    }
}
class Class1 {
    use Trait1, Trait2 {
            Trait2::hello insteadof Trait1;
            Trait1::hi insteadof Trait2;
    }
}
 class Class2 {
    use Trait1, Trait2 {
            Trait2::hello insteadof Trait1;
            Trait1::hi insteadof Trait2;
            Trait2::hi as hei;
            Trait1::hello as hehe;
    }
}
     $Obj1 = new Class1();
    $Obj1->
    hello();
    $Obj1->
    hi();
    echo "\n";
    $Obj2 = new Class2();
    $Obj2->
    hello();
    $Obj2->
    hi();
    $Obj2->
    hei();
    $Obj2->
    hehe();
    

输出

Trait2::helloTrait1::hi  Trait2::helloTrait1::hi Trait2::hiTrait1::hello
?phptrait Hello {
    public function hello() {
            echo "hello,我是周伯通\n";
    }
}
class Class1 {
    use Hello {
            hello as PRotected;
    }
}
class Class2 {
    use Hello {
            Hello::hello as private hi;
    }
}
    $Obj1 = new Class1();
    $Obj1->
    hello();
     # 报致命错误,因为hello方法被修改成受保护的 $Obj2 = new Class2();
    $Obj2->
    hello();
     # 输出: hello,我是周伯通,因为原来的hello方法仍然是公共的$Obj2->
    hi();
      # 报致命错误,因为别名hi方法被修改成私有的
Uncaught Error: Call to protected method Class1::hello() From context '' in D:\web\mytest\p.php:18

Trait 也能组合Trait,Trait中支持抽象方法、静态属性及静态方法,测试代码如下:

?phptrait Hello {
    public function sayHello() {
            echo "Hello 我是周伯通\n";
    }
}
 trait World {
        use Hello;
    public function sayWorld() {
            echo "hello world\n";
    }
        abstract public function getWorld();
    public function inc() {
            static $c = 0;
            $c = $c + 1;
            echo "$c\n";
    }
    public static function DOSomething() {
            echo "Doing something\n";
    }
}
 class HelloWorld {
        use World;
    public function getWorld() {
            return 'do you get World ?';
    }
}
     $Obj = new HelloWorld();
    $Obj->
    sayHello();
    $Obj->
    sayWorld();
    echo $Obj->
    getWorld() . "\n";
    HelloWorld::doSomething();
    $Obj->
    inc();
    $Obj->
    inc();
    

输出

Hello 我是周伯通hello worlddo you get World ?Doing something12

以上就是PHP中Trait的用法及示例的详细内容,更多请关注其它相关文章!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: PHP中Trait的用法及示例
本文地址: https://pptw.com/jishu/596217.html
php实现微信企业付款到零钱 php中的include,require,include

游客 回复需填写必要信息