PHP中Trait的用法及示例-php教程

资源魔 25 0

PHP是单承继的言语,正在PHP 5.4 Traits呈现以前,PHP的类无奈同时从两个基类承继属性或办法,为理解决这个成绩,php出了Trait这个特点。(Traits以及Go言语的组合性能有点相似)

用法:经过正在类中应用use要害字申明要组合的Trait称号,而详细某个Trait的申明应用trait要害词,Trait不克不及间接实例化。

<?php
trait 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蕴含同名属性或许办法时,需求明白申明处理抵触,不然会孕育发生一个致命谬误。

<?php
trait 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是给办法取一个体名,详细用法请看代码:

<?php
trait 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::hello
Trait1::hi 
 
Trait2::hello
Trait1::hi 
Trait2::hi
Trait1::hello
<?php
trait 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中支持形象办法、动态属性及动态办法,测试代码以下:

<?php
trait 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 world
do you get World ?
Doing something12

以上就是PHP中Trait的用法及示例的具体内容,更多请存眷资源魔其它相干文章!

标签: php开发教程 php开发资料 php开发自学 Trait

抱歉,评论功能暂时关闭!