trait
通过引入trait实现代码复用
<?php
trait tDemo
{
public function show()
{
// 打印类中所有属性
return printf("<pre>%s</pre>", print_r(get_class_vars(__CLASS__), true));
}
}
class User
{
use tDemo;
protected $name = '小明';
protected $sex = '男';
}
class User1
{
use tDemo;
protected $name = '小熊';
protected $sex = '男';
}
(new User)->show();
echo '<hr>';
(new User1)->show();
trait的继承应用
<?php
// trait的继承应用
trait tDemo
{
public static function show()
{
// 打印当前类中的方法
return "trait中的方法" . __METHOD__;
}
}
// 父类
abstract class Dad
{
public static function show()
{
return "父类中的方法:" . __METHOD__;
}
}
// 子类(继承父类和引入trait)
class Son extends Dad
{
use tDemo;
public static function show()
{
return "子类中的方法:" . __METHOD__;
}
}
echo Son::show();
如果子类,父类和trait中有同名方法那么调用时优先级子类>trait>父类
trait的扩展
<?php
trait tDemo
{
public static function show()
{
// 打印类中的全部属性
printf("<pre>%s</pre>", print_r(get_class_vars(__CLASS__), true));
}
}
trait tDemo1
{
public static function show1()
{
// 打印类中的全部方法
printf("<pre>%s</pre>", print_r(get_class_methods(__CLASS__), true));
}
}
// 通过引入多个trait实现类的扩展功能
// 也可以通过一个trait整合其他trait,然后通过引入这个trait实现引入多个stait
trait tDemo2
{
use tDemo, tDemo1;
}
class Work
{
// 引入多个trait
use tDemo,tDemo1;
// 引入一个整合的trait
use tDemo2;
public $name = '麻辣小龙虾虾虾';
public $money = '38元/斤';
public function get()
{
return $this->name . ':' . $this->money;
}
}
echo (new Work)->get(), '<hr>';
echo (new Work)->show(), '<hr>';
echo (new Work)->show1(), '<hr>';
trait命名冲突解决方案
<?php
trait tDemo
{
public function get()
{
return __METHOD__;
}
}
trait tDemo2
{
public function get()
{
return __METHOD__;
}
}
// 也可以把所有trait整合
trait tDemo3
{
use tDemo, tDemo2 {
// 给tDemo2中的同名方法取一个别名
tDemo2::get as tg2;
// 把tDemo中的get方法替代掉tDemo中的get方法
tDemo::get insteadof tDemo2;
}
}
// 工作类越简单越好
class Work
{
use tDemo3;
}
echo (new Work)->get(), '<hr>';
// 别名调用方法
echo (new Work)->tg2();
接口和trait的组合应用
<?php
// 可以把接口中的抽象方法在trait中实现然后在工作类中引入trait
// 接口
interface iDemo
{
public static function get();
}
// trait中实现接口中的抽象方法
trait tDemo
{
public static function get()
{
return __METHOD__;
}
}
// 工作类(实现接口并引入trait)
class Demo implements iDemo
{
use tDemo;
}
echo Demo::get();
双色球演示
<?php
// 接口
interface intId
{
public static function getId($min, $max);
}
// 实现接口方法
trait trId
{
public static function getId($min, $max)
{
return mt_rand($min, $max);
}
}
// 创建抽象类引入接口和接口的实现方法
abstract class Lottry implements intId
{
use trID;
// 生成中奖所需号码
protected static function createBalls($min, $max, $num)
{
// 生成中奖号码范围(数组)
$allballs = range($min, $max, 1);
// 根据数量决定是红球还是蓝球
if ($num == 1) return $allballs[array_rand($allballs)];
$redballs = [];
// 获取键名并遍历获取值
foreach (array_rand($allballs, $num) as $key) {
$redballs[] = $allballs[$key];
}
return $redballs;
}
// 中奖方法
abstract protected static function doubleBall($redballs, $blueball);
// 试机号
abstract protected static function shiji($redballs, $buleball, $range);
}
// 子类(工作类)
class Work extends Lottry
{
// 实现抽象类的中奖方法
public static function doubleBall($redballs, $blueball)
{
// 调用抽象类中的方法获取红蓝球的值
$red = self::createBalls(...$redballs);
$blue = self::createBalls(...$blueball);
// 合并
array_push($red, $blue);
return $red;
}
// 实现抽象类中的试机方法
public static function shiji($redballs, $buleball, $range)
{
// 随机生成试机的数量
$count = self::getId(...$range);
// 调用中奖方法
for ($i = 0; $i < $count; $i++) {
$red[] = self::doubleball($redballs, $buleball);
}
return $red;
}
}
$a = Work::doubleBall([1, 33, 6], [1, 16, 1]);
$b = Work::shiji([1, 33, 6], [1, 16, 1], [1, 5]);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
display: flex;
}
.container>.ball {
display: flex;
width: 30px;
height: 30px;
justify-content: center;
align-items: center;
border-radius: 50%;
margin: 5px;
color: white;
box-shadow: 8px 8px 16px lightgray;
}
.container>.ball {
background-color: red;
}
.container>.ball:last-of-type {
background-color: blue;
}
</style>
</head>
<body>
<h2>今日开奖号码</h2>
// 遍历结果集
<div class='container'>
<?php foreach ($a as $key) : ?>
<span class='ball'><?= $key ?></span>
<?php endforeach; ?>
</div>
<h2>今日试机号码</h2>
<?php foreach ($b as $key) : ?>
<div class='container'>
<?php foreach ($key as $k) : ?>
<sapn class='ball'><?= $k ?></sapn>
<?php endforeach ?>
</div>
<?php endforeach ?>
</body>
</html>
总结
1.了解了trait中的各种应用场景
2.了解了trait和接口,抽象类之间的区别