PHP中 Trait的详解
程序员文章站
2022-04-21 19:44:50
...
前言
php从以前到现在一直都是单继承的语言,无法同时从两个基类中继承属性和方法,为了解决这个问题,php出了Trait这个特性
用法:通过在类中使用use 关键字,声明要组合的Trait名称,具体的Trait的声明使用Trait关键词,Trait不能实例化
如以下代码示例:
<?php
trait Kobe{
public $name="kobe";
public function bark(){
echo "My name is kobe";
}
}
class James{
public function lebron(){
echo "My name is james";
}
}
class Curry extends James{
use Kobe;
public function stephen(){
echo "My name is curry";
}
}
$nba = new Curry();
$nba->lebron();
echo "<br/>";
$nba->stephen();
echo "<br/>";
$nba->bark();
将会如下输出:
我们再测试Trait、基类和本类对同名属性或方法的处理,代码如下:
<?php
trait Kobe{
public $name="kobe";
public function name(){
echo "My name is kobe";
}
public function number(){
echo "球衣 24";
}
}
class James{
public function name(){
echo "My name is james";
}
public function number(){
echo "球衣23";
}
}
class Curry extends James{
use Kobe;
public function name(){
echo "My name is curry";
}
}
$nba = new Curry();
$nba->name();
echo "<br/>";
$nba->number();
输出的结果:
所以我们得出的的结论是:trait中的方法会覆盖基类中的同名方法,而本类会覆盖Trait中同名方法
一个类可以组合多个Trait,通过逗号相隔,如下
use trait1,trait2
当不同的trait中,却有着同名的方法或属性,会产生冲突,可以使用insteadof或 as进行解决,insteadof 是进行替代,而as是给它取别名
如下实例:
<?php
trait trait1{
public function name(){
echo "My name is kobe";
}
public function number(){
echo "球衣 24";
}
}
trait trait2{
public function name(){
echo "My name is james";
}
public function number(){
echo "球衣23";
}
}
class nba1{
use trait1,trait2{
trait1::name insteadof trait2;
trait1::number insteadof trait2;
}
}
class nba2{
use trait1,trait2{
trait1::name insteadof trait2;
trait1::number insteadof trait2;
trait2::name as names;
trait2::number as num;
}
}
$NBA1 = new nba1();
$NBA1->name();
echo "<br/>";
$NBA1->number();
echo "<br/>";
echo "<br/>";
echo "<br/>";
$NBA2 = new nba2();
$NBA2->name();
echo "<br/>";
$NBA2->number();
echo "<br/>";
$NBA2->names();
echo "<br/>";
$NBA2->num();
输出结果为:
as 还可以修改方法的访问控制
<?php
trait Nba
{
public function name()
{
echo "My name is kobe";
}
}
class Kobe
{
use Nba {
name as protected;
}
}
class Curry
{
use Nba {
Nba::name as private names;
}
}
$kobe = new Kobe();
$kobe->name();//报错,因为已经把eat改成了保护
$curry = new Curry();
$curry->name();//正常运行,不会修改原先的访问控制
$curry->names();//报错,已经改成了私有的访问控制
Trait也可以互相组合,还可以使用抽象方法,静态属性,静态方法等
trait Kobe{
public function name(){
echo "My name is kobe ";
}
}
trait Lebron{
use Kobe;
public function james(){
echo "My name is James";
}
abstract public function getName();
public function test(){
static $num=0;
$num++;
echo $num;
}
public static function curry(){
echo "My name is curry";
}
}
class animal{
use Lebron;
public function getName(){
echo "This is animal name";
}
}
$animal = new animal();
$animal->getName();
echo "<br/>";
$animal->name();
echo "<br/>";
$animal->james();
echo "<br/>";
$animal::curry();
echo "<br/>";
$animal->test();
echo "<br/>";
$animal->test();
输出结果为:
总结
Trait 表明类可以做什么、提供模块化实现。
Trait是一种代码复用技术,为PHP的单继承限制提供了一套灵活的代码用机制。
工作中哪里用到了trait?
可以再多个类中使用(一个方法需要在多个类中使用)
php5.4开始引入trait,其目的就是在于减少代码的重复,增加代码的复用性。
注意
如何使用Trait、以及Trait的优先级
1、先声明一个trait;
2、在类中使用use将该trait引入。
Trait优先级 :身方法>trait的方法>继承的方法
文章:以上就是PHP中trait的详解,感谢各位大佬的阅读、点赞、评论支持,希望可以帮助到你们。我是 敲码农的小Bug 我们下期见
上一篇: 程序员代码面试指南下(7-9)