资讯专栏INFORMATION COLUMN

php 代码复用机制--traits

yedf / 2421人阅读

摘要:是一种为类似的单继承语言而准备的代码复用机制。因为中的变量环境是基于函数的,所以会输出博客链接代码复用机制,本文后续如有更新将会在博客更新。

提到 php 的代码复用,我们可能第一时间会想到继承,但是这种单继承语言一旦派生的子类过多,那么会产生一系列的问题,比如依赖父类、耦合性太大、破坏了类的封装性。那么有没有更好的方法来实现代码复用呢?

自 PHP 5.4.0 起,PHP 实现了另外一种代码复用的一个方法,称为 traits。

Traits 是一种为类似 PHP 的单继承语言而准备的代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用方法集。Traits 和类组合的语义是定义了一种方式来减少复杂性,避免传统多继承和混入类(Mixin)相关的典型问题。

基础使用方法

Traits 的使用非常简单,只需要在类中使用 use 关键字即可。

</>复制代码

  1. trait A {
  2. public function test() {
  3. echo "trait A::test()";
  4. }
  5. }
  6. class b {
  7. use A;
  8. }
  9. $b=new b();
  10. $b->test();
优先级

简单来说 Trait 优先级大于父类方法,但是小于当前类方法。

</>复制代码

  1. trait A {
  2. public function test() {
  3. echo "trait A::test()";
  4. }
  5. public function test1() {
  6. echo "trait A::test1()";
  7. }
  8. }
  9. class base{
  10. public function test(){
  11. echo "base::test()";
  12. }
  13. public function test1(){
  14. echo "base::test1()";
  15. }
  16. }
  17. class b extends base{
  18. use A;
  19. public function test(){
  20. echo "b::test()";
  21. }
  22. }
  23. $b=new b();
  24. $b->test();//b::test()
  25. $b->test1();//trait A::test1()
Trait冲突问题

在使用多个 Trait 时,如果其中存在相同的方法名称,那么就会产生冲突。使用 insteadof 和 as 可以解决方法名称冲突问题

insteadof可以声明使用两个相同方法名称中的具体某个方法。

</>复制代码

  1. trait A {
  2. public function test() {
  3. echo "trait A::test()";
  4. }
  5. }
  6. trait B {
  7. public function test() {
  8. echo "trait B::test()";
  9. }
  10. }
  11. class c{
  12. use A,B{
  13. A::test insteadof B;//使用 insteadof 明确使用哪个方法
  14. B::test as testB;//使用 as 修改另外一个方法名称,必须在使用 insteadof 解决冲突后使用
  15. }
  16. }
  17. $c=new c();
  18. $c->test();//trait A::test()
  19. $c->testB();//trait B::test()
方法访问控制

使用 as 关键字我们可以对 trait 方法的访问权限进行修改

</>复制代码

  1. trait A {
  2. public function test() {
  3. echo "trait A::test()";
  4. }
  5. private function test1(){
  6. echo "trait A::test1()";
  7. }
  8. }
  9. class b{
  10. use A{
  11. test as protected;
  12. test1 as public test2;//更改权限时还可以修改名称
  13. }
  14. }
  15. $b=new b();
  16. $b->test();//Fatal error: Call to protected method b::test()
  17. $b->test2();//trait A::test1()
Trait嵌套使用

</>复制代码

  1. trait A {
  2. public function test1() {
  3. echo "test1";
  4. }
  5. }
  6. trait B {
  7. public function test2() {
  8. echo "test2";
  9. }
  10. }
  11. trait C {
  12. use A,B;
  13. }
  14. class D {
  15. use C;
  16. }
  17. $d = new D();
  18. $d->test2(); //test2
变量、属性、方法定义

Trait可定义属性,但类中不能定义同样名称属性

</>复制代码

  1. trait A {
  2. public $test1;
  3. }
  4. class B {
  5. use A;
  6. public $test;
  7. public $test1;//Strict Standards: B and A define the same property ($test1) in the composition of B...
  8. }

Trait支持抽象方法、支持静态方法、不可以直接定义静态变量,但静态变量可被trait方法引用。

</>复制代码

  1. trait A {
  2. public function test1() {
  3. static $a = 0;
  4. $a++;
  5. echo $a;
  6. }
  7. abstract public function test2(); //可定义抽象方法
  8. }
  9. class B {
  10. use A;
  11. public function test2() {
  12. }
  13. }
  14. $b = new B();
  15. $b->test1(); //1
  16. $b->test1(); //2
对比javascript

这种 trait use 的使用方法大概和 javascript 中的 call 有点相似,都是把一个另外一个对象挂载到当前对象的执行环境当中。当然 javascript 是基于原型的语言。两者也没有可比性。仅仅是使用方法相差无几,有助于理解。

</>复制代码

  1. function a() {
  2. this.name="a";
  3. this.getName=function(){
  4. console.log(this.name);
  5. }
  6. }
  7. function b(){
  8. this.name="b";
  9. a.call(this);
  10. }
  11. var b = new b();
  12. b.getName();//a

因为 javascript 中的变量环境是基于函数的,所以会输出a

博客链接:php 代码复用机制--traits,本文后续如有更新将会在博客更新。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/23039.html

相关文章

  • 简述我所理解的 PHP Trait

    摘要:和组合的语义定义了一种减少复杂性的方式,避免传统多继承和类相关典型问题。队列的目的是将耗时的任务延时处理,比如发送邮件,从而大幅度缩短请求和相应的时间。同样的道理,根据引入不同的来完成对应的功能。 showImg(https://segmentfault.com/img/remote/1460000010868178); Trait 概念 在常规的 PHP 开发中,我们都习惯于先编写一...

    gecko23 评论0 收藏0
  • 关于PHP的Trait特性

    摘要:关于作者程序开发人员,不拘泥于语言与技术,目前主要从事和前端开发,使用和,端使用混合式开发。和组合的语义定义了一种减少复杂性的方式,避免传统多继承和类相关典型问题。它为传统继承增加了水平特性的组合也就是说,应用的几个之间不需要继承。 关于作者 程序开发人员,不拘泥于语言与技术,目前主要从事PHP和前端开发,使用Laravel和VueJs,App端使用Apicloud混合式开发。合适和...

    wind3110991 评论0 收藏0
  • PHP 特性之 trait (一)

    摘要:在阅读文档的时候看到一个类是以声明的。是一种代码复用技术,为的单继承限制提供了一套灵活的代码复用机制。下面把的代码做一个修改以上代码会输出。可以看出优先级的顺序为,当前类的优先级基类。   在阅读laravel文档的时候看到一个类 是以 Trait声明的。平时在工作中从来没有用过,于是就去看了下官方文档。原来这个类早在php5.4.0就有了。可惜在项目中从来没有用过。   Trait看...

    ermaoL 评论0 收藏0
  • 关于Trait

    摘要:自起,实现了一种代码复用的方法,称为。为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用。优先级从基类继承的成员会被插入的成员所覆盖。优先顺序是来自当前类的成员覆盖了的方法,而则覆盖了被继承的方法。 自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 Trait。 Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait ...

    My_Oh_My 评论0 收藏0
  • 玩转PHP的Trait

    摘要:语言的一个问题是单继承,这意味着类只能继承一个其他的类。然而,很多情况下需要多继承,比如继承多个类的方法,以防止代码的重复。和组合的语义定义了一种减少复杂性的方式,避免传统多继承问题。是一组方法,可以包含在类中进行使用,单不可实例化。 PHP语言的一个问题是单继承,这意味着类只能继承一个其他的类。然而,很多情况下需要多继承,比如继承多个类的方法,以防止代码的重复。对于但继承模式好还是多...

    hikui 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<