站长资讯网
最全最丰富的资讯网站

总是在重复,气抖冷,trait何时才能站起来?

类中的某些成员如何才能被其他类使用呢?使用继承的话,这继承链也太长了,php提供了代码复用技术trait。

1.定义Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。trait可以使得单继承语言拜托为了复用而不得不继承的尴尬,让面向对象变得更加纯粹。

2.基础语法

trait是一种类似class的关键字。

<?php      trait Eat{         public $a=10;      //trait内允许有类的成员属性(包括静态属性),成员方法(包括静态方法)         public static $b=666;         //const c=3.14;       //trait内不允许有常量         protected $e;	//允许定义,但是实际不用         private $f;         public function getA()         {                echo $this->a,"<br>";         }         public static function getB()         {                echo self::$b,"<br>";         }     } ?>

trait是用来实现代码的复用的,不可以被实例化也不可以被继承(不是类)。

<?php    trait Eat{}   // $a=new Eat;//报错   //calss A extends Eat{}//报错 ?>

3.trait的使用

trait只是一段代码的集合,使用时必须要使用use进行引用。

<?php          trait Eat{         public $a=10;         public static $b=666;         //const c=3.14;         public function getA()         {                echo $this->a,"<br>";         }         public static function getB()         {                echo self::$b,"<br>";         }     }          class A{         use Eat;           public function getC()         {             echo $this->a,"<br>";         }     }      $boy=new A();     $boy->getC();     $boy->getA();     $boy->getB(); ?>

一个类可以使用多个trait。

<?php    trait A1{    }    trait A2{    }    class People{      use A1,A2;    } ?>

4.trait使用的问题

a.如果同时引入的多个trait中有同名属性,那么会产生冲突。

<?php     trait A1{        public $a=11;     }     trait A2{        public $a=22;     }      class A3{         use A1,A2;//不允许同名属性         public function geta(){             echo $this->a;         }     }      $example=new A3();     ?>

b.如果同时引入的多个trait中有同名方法,那么会产生冲突,有两种方案解决如A3、A4。

<?php     trait A1{        public $a=11;        public function eat(){            echo "A1中eat()方法","<br>";        }     }     trait A2{        public $b=22;        public function eat(){         echo "A2中eat()方法","<br>";       }     }      class A3{         use A1,A2{           A1::eat insteadOf A2; //A1中的eat替代A2中的eat         }     }     class A4{         use A1,A2{             A1::eat insteadOf A2;//A1中的eat替代A2中的eat             A2::eat as eat2;     //A2中的eat取别名eat2           }     }      $example=new A3();     $example->eat();     $example=new A4();     $example->eat2(); ?>

c.同名覆盖问题:如果类中有与引入的trait同名成员,会有不同处理:

  • 属性:不允许重名,即类中不允许定义与trait中同名的成员属性(静态属性也一样)。

  • 方法:类覆盖trait。

d.继承覆盖问题:如果类中在使用trait的同时,也是继承自父类,而trait中与父类中有同名方法,那么trait中将覆盖父类同名方法;如果要访问父类方法,可以在trait同名方法中使用parent关键字访问父类同名方法。

<?php     trait Eat{     public function eat(){         echo 'Eat::eat';     } }     class Human{     public function eat(){         echo 'Human::eat';     } } //子类继承父类同时使用trait class Man extends Human{     use Eat; }  $m = new Man(); $m->eat(); ?>

e.trait自己不能访问,只是用来给其他类提供代码复用的,因此允许类在使用trait时更高里面方法的访问控制权:在as之后,使用目标访问修饰限定符。

<?php trait Eat{     private function show(){         echo 'eat';     } } class Human{     use Eat{         show as public eshow;				         //注意:as是用来设定别名的,虽然没有同名show,但是系统认为show已经存在,所以必须别名,权限的更改的方法不是         //本尊     } } $h = new Human(); $h->eshow();								//eat ?>

f.trait中可以使用抽象方法,用来规范使用类必须实现对应抽象方法:使用类要么为抽象类,要么就必须实现抽象方法。

<?php    trait Eat{      public function eat();		//抽象方法    }    abstract class Human{			     use Eat;					//抽象类:可以不实现抽象方法    }     class Animal{     use Eat;     public function eat(){		//具体类:实现抽象方法         echo 'Animal::eat';	     }		 } ?>

推荐:php教程,php视频教程

赞(0)
分享到: 更多 (0)
网站地图   沪ICP备18035694号-2    沪公网安备31011702889846号