自PHP5.4.0起,PHP实现了一种代码复用的方法,称为trait。
众所周知,PHP中是单继承的,trait是为类似PHP的单继承语言而准备得一种代码复用机制。trait为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用method。trait和class组合的语义定义了一种减少复杂性的方式,避免传统多继承问题。
trait和class相似,但仅仅在用细粒度和一致的方式来组合功能。无法通过trait自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个class之间不需要继承。
简单的例子
首先我们举个例子来介绍trait,和类定义相似,但使用关键字trait定义。在类中使用use组合。
<?php
trait T{
    public function t1(){
        return 't1';
    }
 
 
    public function t2(){
        return 't2';
    }
}
 
 
class Demo{
    use T;
    public function test(){
        return 'test';
    }
}
 
 
$demo = new Demo;
echo $demo->t1(),'</br>';
echo $demo->test();
输出结果:
多个trait冲突解决
​如果使用多个trait,但是出现了方法名相同,这就出现了冲突,就要手动指定使用哪个trait的方法,使用insteadof关键字实现。
<?php
trait T{
    public function t1(){
        return 't1';
    }
 
 
    public function t2(){
        return 't2';
    }
}
 
 
trait T2{
    public function t1(){
        return 't3';
    }
}
 
 
class Demo{
    use T,T2{
        //使用T的m1方法
        T::t1 insteadof T2;
    }
    public function test(){
        return 'test';
    }
}
 
 
$demo = new Demo;
echo $demo->t1(),'</br>';
echo $demo->test();
输出结果:
​在冲突的时候,也可以使用use定义方法别名解决冲突,例子如下:
<?php
trait T{
    public function t1(){
        return 't1';
    }
 
 
    public function t2(){
        return 't2';
    }
}
 
 
trait T2{
    public function t1(){
        return 't3';
    }
}
 
 
class Demo{
    use T,T2{
        //使用T的m1方法
        T::t1 insteadof T2;
        T2::t1 as new_t1;
    }
    public function test(){
        return 'test';
    }
}
 
 
$demo = new Demo;
echo $demo->t1(),'</br>';
echo $demo->new_t1(),'</br>';
echo $demo->test();
输出结果:
改变访问权限
​也可以使用use关键字来改变方法的访问权限。
<?php
trait T{
    public function t1(){
        return 't1';
    }
 
 
    public function t2(){
        return 't2';
    }
}
 
 
class Demo{
    use T{
        t2 as protected;
    }
    public function test(){
        return 'test';
    }
}
 
 
$demo = new Demo;
echo $demo->t1(),'</br>';
echo $demo->t2(),'</br>';
echo $demo->test();
输出结果:
上面只是介绍了一些常用的特性,详细可参考官方手册: https://php.net/manual/zh/language.oop5.traits.php

PHP学习之PHP trait解析的更多相关文章

  1. [置顶] Android学习系列-Android中解析xml(7)

    Android学习系列-Android中解析xml(7) 一,概述 1,一个是DOM,它是生成一个树,有了树以后你搜索.查找都可以做. 2,另一种是基于流的,就是解析器从头到尾解析一遍xml文件.   ...

  2. 标准Trie字典树学习一:原理解析

    特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! 系列文章: 1. 字典树Trie学习一:原理解析 2.字典树Tr ...

  3. NVIDIA深度学习Tensor Core性能解析(下)

    NVIDIA深度学习Tensor Core性能解析(下) DeepBench推理测试之RNN和Sparse GEMM DeepBench的最后一项推理测试是RNN和Sparse GEMM,虽然测试中可 ...

  4. NVIDIA深度学习Tensor Core性能解析(上)

    NVIDIA深度学习Tensor Core性能解析(上) 本篇将通过多项测试来考验Volta架构,利用各种深度学习框架来了解Tensor Core的性能. 很多时候,深度学习这样的新领域会让人难以理解 ...

  5. LevelDB学习笔记 (3): 长文解析memtable、跳表和内存池Arena

    LevelDB学习笔记 (3): 长文解析memtable.跳表和内存池Arena 1. MemTable的基本信息 我们前面说过leveldb的所有数据都会先写入memtable中,在leveldb ...

  6. 学习SpringMVC——说说视图解析器

    各位前排的,后排的,都不要走,咱趁热打铁,就这一股劲我们今天来说说spring mvc的视图解析器(不要抢,都有位子~~~) 相信大家在昨天那篇如何获取请求参数篇中都已经领略到了spring mvc注 ...

  7. nodejs学习笔记二:解析express框架项目文件

    上一章介绍了如何去创建一个express框架的工程项目,这章介绍一下express框架下的文件和用法解析,上一张我们创建的工程项目结构图如下: models是不属于原工程项目结构,为了实现数据模型后添 ...

  8. 【Android学习笔记】XmlResourceParser解析xml文件

    最近学习Android时,需要用到解析XML文件里的数据,可以用XmlResourceParser来解析xml文件,正好将此记录下来. XmlResourceParser里常用的字段和方法 首先先给出 ...

  9. Android源代码学习之六——ActivityManager框架解析

    ActivityManager在操作系统中有关键的数据,本文利用操作系统源代码,逐步理清ActivityManager的框架,并从静态类结构图和动态序列图两个角度分别进行剖析,从而帮助开发者加强对系统 ...

随机推荐

  1. idea svn设置忽略提交文件

    1.找到版本控制位置 2.新建变动列表(装载忽略的文件内容) 3. 将默认的变动列表中需要忽略的文件拖入ignored列表下 4. 提交时,选择default即可. 设置完毕之后,可以在提交文件时将之 ...

  2. 程序猿必备的Git教程

    http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 版权声明:本文为博主原创文章,未经 ...

  3. Spring Cloud|高可用的Eureka集群服务

    Eureka,作为spring cloud的服务发现与注册中心,在整个的微服务体系中,处于核心位置.单一的eureka服务,显然不能满足高可用的实际生产环境,这就要求我们配置一个能够应对各种突发情况, ...

  4. Linux设备驱动程序 之 内核定时器

    综述 如果需要在将来的某个时间点调度执行某个动作,同时在该时间点到达之前不会阻塞当前进程,则可以使用内核定时器: 内核定时器是一个数据结构,它告诉内核在用户定义的时间点使用用户定义的参数来执行一个用户 ...

  5. FMX开源控件

    FMX开源控件 这是群友谢顿做的控件,必须赞一个! https://github.com/zhaoyipeng/FMXComponents 这是loki的: https://sourceforge.n ...

  6. [Oracle]关于回滚段的一些转贴摘录

    ORACLE 回滚段 回滚段概述 回滚段用于存放数据修改之前的值(包括数据修改之前的位置和值).回滚段的头部包含正在使用的该回滚段事务的信息.一个事务只能使用一个回滚段来存放它的回滚信息,而一个回滚段 ...

  7. java定时任务Timer/scheduleAtFixedRate

    Timer类是用来执行任务的类,定时器 scheduleAtFixedRate模式可以用,在这个模式下,Timer会尽量的让任务在一个固定的频率下运行. 参考:http://swiftlet.net/ ...

  8. 10 Flutter仿京东商城项目 商品分类跳转到商品列表传值 商品列表页面布局

    pages下面新建: ProductList.dart import 'package:flutter/material.dart'; import '../services/ScreenAdaper ...

  9. 【404】int main(int argc,char * argv[]) windows 下的使用

    参考:int main(int argc,char * argv[]) windows 下的使用 参考:Theprogram can't start because libgcc_s_dw2-1.dl ...

  10. windows注册服务

    Windows服务是运行一些服务程序的较好方式(这些程序专门为各种功能提供服务,无操作界面,运行在后台),其创建方法也很简单,通过系统自带的sc命令即可方便的创建. sc命令创建Windows服务的方 ...