php从以前到现在一直都是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php出了Trait这个特性。
与普通类的区别:
trait 能够像普通的类一样定义属性,方法(包含抽象的、静态的、抽象的);
trait 引入到基类里面,其子类里面也能访问trait里面的属性和方法。
trait不用实例化就能访问定义的普通方法以及属性。
trait里面不能定义构造函数。
trait的使用:
<?php
trait dog{
public $name = 'dog';
public function run(){
echo "dog run";
}
}
class Animal{
public function eat(){
echo "animal eat";
}
}
class cat extends Animal{
use dog;
public function play(){
echo "cat play";
}
}
$cat = new cat();
$cat->play();
echo "<br/>";
$cat->eat();
echo "<br/>";
$cat->run();
将会如下输出:
本类、基类和trait类中存在同名属性和方法时:
<?php
trait dog{
public $name = 'dog';
public function run(){
echo "dog run";
}
public function eat(){
echo "dog eat";
}
public function play(){
echo "dog play";
}
}
class Animal{
public function eat(){
echo "animal eat";
}
public function play(){
echo "animal play";
}
}
class cat extends Animal{
use dog;
public function play(){
echo "cat play";
}
}
$cat = new cat();
$cat->play();
echo "<br/>";
$cat->eat();
echo "<br/>";
$cat->run();
echo "<br/>";
echo $cat->name;
输出如下:
可以看到trait中的方法会覆盖基类中的同名方法,而本类会覆盖trait中同名方法。如果在Animal和cat类中再定义$name属性时会产生fatal error。
多个trait继承:
<?php
trait trait1{
public function eat(){
echo "This is trait1 eat";
}
public function drive(){
echo "This is trait1 drive";
}
}
trait trait2{
public function eat(){
echo "This is trait2 eat";
}
public function drive(){
echo "This is trait2 drive";
}
}
class cat{
use trait1,trait2{
trait1::eat insteadof trait2;
trait1::drive insteadof trait2;
}
}
class dog{
use trait1,trait2{
trait1::eat insteadof trait2;
trait1::drive insteadof trait2;
trait2::eat as eaten;
trait2::drive as driven;
}
}
$cat = new cat();
$cat->eat();
echo "<br/>";
$cat->drive();
echo "<br/>";
echo "<br/>";
echo "<br/>";
$dog = new dog();
$dog->eat();
echo "<br/>";
$dog->drive();
echo "<br/>";
$dog->eaten();
echo "<br/>";
$dog->driven();
输出如下:
trait间的使用:
<?php
trait Cat{
public function eat(){
echo "This is Cat eat";
}
}
trait Dog{
use Cat;
public function drive(){
echo "This is Dog drive";
}
abstract public function getName();
public function test(){
static $num=0;
$num++;
echo $num;
}
public static function say(){
echo "This is Dog say";
}
}
class animal{
use Dog;
public function getName(){
echo "This is animal name";
}
}
$animal = new animal();
$animal->getName();
echo "<br/>";
$animal->eat();
echo "<br/>";
$animal->drive();
echo "<br/>";
$animal::say();
echo "<br/>";
$animal->test();
echo "<br/>";
$animal->test();
输出如下: