php静态类和动态类的区别(PHP Trait代码复用类与多继承实现方法详解)
php静态类和动态类的区别
PHP Trait代码复用类与多继承实现方法详解本文实例讲述了php trait代码复用类与多继承实现方法。分享给大家供大家参考,具体如下:
前言
众所周知,一直以来php和很多语言一样是单继承的语言,但是常常在编码过程中,我们需要在当前类中使用两个或两个以上的其他类的方法,这种情况下继承就不能实现,而往往采用new方式实例化很多要用到的类,这样就会很影响代码的结构和开发规范。于是trait类诞生了,它是一种代码复用的语法,能够实现一个类中引用多个其他类的方法。
一、概念
php官方手册对trait的描述是:
trait是为类似php的单继承语言而准备的一种代码复用机制。trait为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用method。trait和class组合的语义定义了一种减少复杂性的方式,避免传统多继承和mixin类相关典型问题。
trait和class相似,但仅仅旨在用细粒度和一致的方式来组合功能。无法通过trait自身来实例化。它为传统继承增加了水平特性的组合;也就是说,应用的几个class之间不需要继承。
二、trait类的使用
简单地讲,trait就是一种不同于继承的语法,定义一个trait类,在其他类中使用它则是采用use关键字,有点类似于命名空间的用法,但是含义不同。use关键字在一个类中引入trait类后,相当于require或include了一段代码进来,不同之处在于use的trait类与当前类是可以看做同一个类的,即当前类可以用$this关键字调用trait类的方法。
以下是原理解释:
可以看出当前类可以简单地use两个trait类,并调用其中的方法,而不仅限于继承,只能使用一个父类的方法。
三、trait类的访问控制
我们知道,继承的方式,如果基类是private修饰控制的,则子类是无法调用的。但是trait
不一样,因为它类似于require到当前类中了,所以不管是public、protected或private都是可以直接使用的。示例如下:
四、trait类的优先级控制
trait类与当前使用类、继承的基类之间的调用优先级顺序如下:
当前使用类>trait类>继承的基类
当存在同名方法时,会根据优先级覆盖掉同名的类。具体示例如下:
1、trait类覆盖基类
2、当前类覆盖trait类
五、多个trait类的冲突控制
在php中,如果当前类use了两个trait类,同时两个trait类都存在一个同名的方法,此时如果没有明确解决冲突将会产生一个致命错误。
对于这种情况,php官方给出了两个解决方案:
1、insteadof关键字:通过该关键字指定方法名冲突时该使用哪个trait类的方法,即:
如果c类use了a、b两个trait类,且a、b两个类都存在a、b方法,则在c类use a、b类时使用insteadof声明冲突的解决方法即可:
|
use a, b { b::a insteadof a; //a方法冲突时使用b类的a方法而不使用a类的a方法 a::b insteadof b; //b方法冲突时使用a类的b方法而不使用b类的b方法 } |
2、as关键字:通过as关键字将同名方法指定为一个别名,且仅作用于当前类中。示例如下:
|
use a, b { b::a as c; //声明b类的a方法为c,作用于该类 a::b as d; //声明a类的b方法为d,作用于该类 } |
六、与继承、直接实例化的区别
对于当前一个类需要用到另一个或多个类的方法的情况,我们一般会想到的方式有继承、直接实例化另外一个或多个类等等的方法,下面来对比一下这些方法和trait类的区别:
1、继承方式:对于继承,可以完美地复用另一个类的一些方法,但是对于需要复用多个类的方法时,php是不支持多继承的,而且只能访问public和protected方法;
2、与直接实例化的区别:我们也可以在当前类中直接实例化要用到的a类与b类,但是这种方法在控制访问范围反面,只允许访问a、b类中public的方法;
3、使用trait类则完全将a、b两个类的方法导入到当前类中,可以视为当前类的一部分,唯一区别是可以存在于当前类同名的方法,此时由优先级顺序来控制。
补充:php多继承示例
|
class base{ public function sayhello(){ echo "hello " ; } } trait sayworld{ public function sayhello(){ parent::sayhello(); echo "world" .php_eol; } } trait sayworld2{ public function sayhello2(){ echo "php" .php_eol; } } class myhelloworld extends base{ use sayworld,sayworld2; } $s = new myhelloworld(); $s ->sayhello(); $s ->sayhello2(); |
输出结果:
hello world
php
希望本文所述对大家php程序设计有所帮助。
原文链接:https://blog.csdn.net/dream_successor/article/details/78481265
- 解释php中可变变量并举例说明(PHP Primary script unknown 解决方法总结)
- php 数据库查询并写入(PHP实现单条sql执行多个数据的insert语句方法)
- php上传图片视频代码(详解PHP素材图片上传、下载功能)
- 阿里云服务器怎么搭建环境(阿里云服务器快速配置php环境的方法)
- thinkphp5.1修改(ThinkPHP 5.1 跨域配置方法)
- centos安装php5.6(Centos7 Yum安装PHP7.2流程教程详解)
- php 依赖注入(详解php命令注入攻击)
- phpstudy服务器怎么设置(phpstudy2018 访问目录服务权限问题)
- phpstudy安装包打不开(phpStudy访问速度慢和启动失败的解决办法)
- php面向对象final怎么设置(PHP面向对象程序设计中的self、static、parent关键字用法分析)
- php检查语法(使用 PHP Masked Package 屏蔽敏感数据的实现方法)
- php时间戳是什么意思(php时间戳转换代码详解)
- linux怎么设置php代码(linux Cron定时执行带参数的PHP代码)
- dedecms版本介绍(解决更换PHP5.4以上版本后Dedecms后台登录空白问题的方法)
- php 会话session实现用户登录功能(PHP cookie,session的使用与用户自动登录功能实现方法分析)
- php如何实现异步调用(php基于协程实现异步的方法分析)
- 十二星座爱情支配欲指数(十二星座爱情支配欲指数)
- 虐待儿童是发泄支配欲的愚蠢行为(虐待儿童是发泄支配欲的愚蠢行为)
- 你或许不知道你隐藏的支配欲望(你或许不知道你隐藏的支配欲望)
- 把宽体丰田86卖了,换成7.5代高尔夫GTI玩起姿态与性能并存的改装(把宽体丰田86卖了)
- 大众推出了第五代高尔夫GT(大众推出了第五代高尔夫GT)
- 换代在即,现在是抄底 7.5代 高尔夫的最佳时机吗(换代在即现在是抄底)
热门推荐
- docker容器映射到宿主机器(在宿主机上执行docker容器内部的shell或程序方式)
- apache配置403错误提示(apache documentroot指向htcdoc之外提示403错误的解决方法)
- yield方法可以使一个线程停止运行(Yii2.0框架模型添加/修改/删除数据操作示例)
- sqlserver电脑休眠时断开连接(浅谈sqlserver下float的不确定性)
- dede搜索模块下载(dede会员列表调用适用于企业、个人)
- python 爬虫图形验证码(Python爬虫实现验证码登录代码实例)
- python中可以改变的数据类型(Python常见数据类型转换操作示例)
- python异常值处理(一篇文章带你弄懂Python异常传递和自定义异常)
- nginx配置https转发规则(Nginx配置https原理及实现过程详解)
- python解析视频源码(基于python实现高速视频传输程序)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9