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

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

如下代码实例:

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

将会如下输出

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

如下显示

 
Paste_Image.png

所以:Trait中的方法会覆盖 基类中的同名方法,而本类会覆盖Trait中同名方法
注意点:当trait定义了属性后,类就不能定义同样名称的属性,否则会产生 fatal error,除非是设置成相同可见度、相同默认值。不过在php7之前,即使这样设置,还是会产生E_STRICT 的提醒

一个类可以组合多个Trait,通过逗号相隔,如下

use trait1,trait2

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

<?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

最新文章

  1. css元素排列
  2. JVM体系结构与工作方式
  3. VS2013编译python源码
  4. redis安装,配置
  5. 获取JDBC中的ResultSet的记录的条数
  6. PHP FTP操作类( 上传、拷贝、移动、删除文件/创建目录 )
  7. (转)要“jquery”ScriptResourceMapping。请添加一个名为 jquery (区分大小写)的 ScriptResourceMapping。”的解决办法。
  8. 115太酷了,居然出了个TV版客户端
  9. shape及其子节点详解
  10. 运营总监招聘-e袋洗招聘-拉勾网
  11. 手把手教你使用Git(转)
  12. [转载]linux下编译php中configure参数具体含义
  13. django-查询语句(一)
  14. ObjectiveC 深浅拷贝学习
  15. VMware vCenter Server 6.5.0 U1
  16. Asp.net 在刷新或提交页面后保持滚动条的位置
  17. 【Jmeter】Address already in use : connect &amp;&amp;Permission denied: connect 解决方案
  18. 第一章 C++语言入门
  19. Dottrace 10.0.2 使用心得
  20. 关于k8s这项大动作,预示着边缘计算迎来“开源”发展的新周期……

热门文章

  1. [LeetCode]617. 合并二叉树(递归)
  2. 认证授权:IdentityServer4 - 单点登录
  3. Java 中 static 的作用
  4. websocket直接绕过JS加密的方式
  5. 在Notepad++中配置python运行环境
  6. Java多线程--公平锁与非公平锁
  7. Redis常见的八道面试题
  8. 从CPU缓存看缓存的套路
  9. 使用jsonify返回json数据
  10. 基于python的webUI自动化-小白基础篇