Correcting teacher:天蓬老师
Correction status:qualified
Teacher's comments:trait的本质是代码复用,重点放在它的功能组合与命名冲突的解决上
<?php
//1.trait功能1:代码复用
trait tDemo
{
public function show()
{
//get_class_vars — 返回由类的默认属性组成的数组
printf('<pre>%s</pre>',print_r(get_class_vars(__CLASS__),true));
}
}
class User1
{
use tDemo;
protected $name = '胖子';
protected $sex = '男';
}
class User2
{
use tDemo;
protected $name = '胖子';
protected $sex = '男';
}
(new User1)->show();
(new User2)->show();
<?php
//trait功能2:在继承上下文中的应用
trait tDemo
{
//public static $name = 'trait中的属性';
public static function hello()
{
//__METHOD__返回类名称与函数名称
//__FUNCTION__返回函数名称
return 'trait中的方法' . __METHOD__;
}
}
//声明一个抽象类 基类/父类/超类
abstract class Dad
{
public static $name = '基类中的属性';
public static function hello()
{
//__METHOD__返回类名称与函数名称
//__FUNCTION__返回函数名称
return '基类中的方法' . __METHOD__;
}
}
//子类/扩展类
class Son extends Dad
{
//引入trait
use tDemo;
public static $name = '扩展类中的属性';
public static function hello()
{
//__METHOD__返回类名称与函数名称
//__FUNCTION__返回函数名称
return '扩展类中的方法' . __METHOD__;
}
}
echo Dad::$name.'<br>';
echo Dad::hello().'<hr>';
//子类同名成员优先级大于父类同名成员
//如果子类,父类,trait中存在同名方法的时候,而trait在子类中调用,此时
//子类>trait>父类
echo Son::$name.'<br>';
echo Son::hello();
<?php
//trait功能3: 实现功能扩展
//trait1
trait tDemo1
{
//1.打印所有属性
public function getProps()
{
//__CLASS__返回当前类的名称字符串
//self:返回当前类的引用
printf('<pre>%s</pre>',print_r(get_class_vars(__CLASS__),true));
}
}
//trait2
trait tDemo2
{
//2.打印所有方法
public function getMethods()
{
printf('<pre>%s</pre>',print_r(get_class_methods(__CLASS__),true));
}
}
//trait3,合并trait1,trait2
trait tDemo3
{
use tDemo1,tDemo2;
}
class Work1
{
use tDemo3;
public $name = '西瓜';
public $price = 0.7;
public function getInfo()
{
return $this->name . ':' . $this->price;
}
//扩展这个类的功能
//添加二个方法
//1.打印所有属性
//2.打印所有方法
}
echo (new Work1)->getInfo(),'<hr>';
echo (new Work1)->getProps(),'<hr>';
echo (new Work1)->getMethods(),'<hr>';
<?php
//trait功能4:在trait组合中命名冲突的解决方案
trait tDemo1
{
public function display()
{
//__TRAIT__:返回trait的名称字符串
return __TRAIT__;
}
}
trait tDemo2
{
public function display()
{
//__TRAIT__:返回trait的名称字符串
return __METHOD__;
}
}
trait tDemo3
{
use tDemo1,tDemo2{
//给tDemo2::display()起个别名:td2
tDemo2::display as td2;
//调用tDemo1::display()替换掉tDemo2::display()
tDemo1::display insteadof tDemo2;
}
}
//工作类尽可能写的代码清晰,简洁
class Work
{
use tDemo3;
}
echo (new Work)->display(),'<hr>';
//别名访问
echo (new Work)->td2();
<?php
//trait功能5:trait和interface的组合
//接口
//如果这个接口不存在的话,直接创建这个接口
if (!interface_exists('iDemo')):
interface iDemo
{
public static function index();
}
endif;
//trait
if(!trait_exists('tDemo')):
trait tDemo
{
//将接口中的抽象方法的实现过程放在trait中实现,并在工作中调用
public static function index()
{
return __METHOD__;
}
}
endif;
//实现类
if(!class_exists('Hello')):
class Hello implements iDemo
{
use tDemo;
}
endif;
//客户端调用
echo Hello::index();
<?php
//实战:双色球开奖
//抽象类 + 接口 + trait
//奖品
$prizes = ['华为p40手机','山地自行车','机械键盘','音箱','耳机','头盔'];
/* trait iCreateId
{
//生成一个唯一的ID
public static function generateId($min,$max)
{
//返回范围内的随机整数
return mt_rand($min,$max);
}
} */
interface iCreateId
{
public static function generateId($min,$max);
}
trait CreateId
{
public static function generateId($min,$max)
{
//返回范围内的随机整数
return mt_rand($min,$max);
}
}
//开奖类
class DrawPrize implements iCreateId
{
use CreateId;
//发奖品
public static function award($prizes,$id)
{
return $prizes[$id];
}
}
$id = DrawPrize::generateId(0,5);
$prize = DrawPrize::award($prizes,$id);
printf('奖品是:<span style="color:red">%s</span>',$prize);