php 中trait的使用

php从之前到如今一直都是单继承的语言,没法同时从两个基类中继承属性和方法,为了解决这个问题,php出了Trait这个特性php

用法:经过在类中使用use 关键字,声明要组合的Trait名称,具体的Trait的声明使用Trait关键词,Trait不能实例化测试

以下代码实例:spa

<?php
trait Dog{
    public $name="dog";
    public function bark(){
        echo "This is dog";
    }
}
class Animal{
    public function eat(){
        echo "This is animal eat";
    }
}
class Cat extends Animal{
    use Dog;
    public function drive(){
        echo "This is cat drive";
    }
}
$cat = new Cat();
$cat->drive();
echo "<br/>";
$cat->eat();
echo "<br/>";
$cat->bark();
?>

将会以下输出code

Paste_Image.png继承

再测试Trait、基类和本类对同名属性或方法的处理,以下代码

<?php
trait Dog{
    public $name="dog";
    public function drive(){
        echo "This is dog drive";
    }
    public function eat(){
        echo "This is dog eat";
    }
}

class Animal{
    public function drive(){
        echo "This is animal drive";
    }
    public function eat(){
        echo "This is animal eat";
    }
}

class Cat extends Animal{
    use Dog;
    public function drive(){
        echo "This is cat drive";
    }
}
$cat = new Cat();
$cat->drive();
echo "<br/>";
$cat->eat();

?>

以下显示get

Paste_Image.pngit

因此:Trait中的方法或属性会覆盖 基类中的同名的方法或属性,而本类会覆盖Trait中同名的属性或方法io

一个类能够组合多个Trait,经过逗号相隔,以下

use trait1,trait2ast

当不一样的trait中,却有着同名的方法或属性,会产生冲突,能够使用insteadof或 as进行解决,insteadof 是进行替代,而as是给它取别名
以下实例:function

<?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();
?>

输出以下

Paste_Image.png

as 还能够修改方法的访问控制

<?php
trait Animal{
    public function eat(){
        echo "This is Animal eat";
    }
}

class Dog{
    use Animal{
        eat as protected;
    }
}
class Cat{
    use Animal{
        Animal::eat as private eaten;
    }
}
$dog = new Dog();
$dog->eat();//报错,由于已经把eat改为了保护

$cat = new Cat();
$cat->eat();//正常运行,不会修改原先的访问控制
$cat->eaten();//报错,已经改为了私有的访问控制
?>

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();
?>

输出以下

做者:依恋灬 连接:https://www.jianshu.com/p/fc053b2d7fd1 來源:简书 简书著做权归做者全部,任何形式的转载都请联系做者得到受权并注明出处。

相关文章
相关标签/搜索