php 代码复用机制
https://juejin.im/entry/5927ec4544d904006413f61d
提到 php 的代码复用,我们可能第一时间会想到继承,但是这种单继承语言一旦派生的子类过多,那么会产生一系列的问题,比如依赖父类、耦合性太大、破坏了类的封装性。那么有没有更好的方法来实现代码复用呢?
自 PHP 5.4.0 起,PHP 实现了另外一种代码复用的一个方法,称为 traits。
Traits 是一种为类似 PHP 的单继承语言而准备的代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用方法集。Traits 和类组合的语义是定义了一种方式来减少复杂性,避免传统多继承和混入类(Mixin)相关的典型问题。
基础使用方法
Traits 的使用非常简单,只需要在类中使用 use 关键字即可。
trait A {
public function test() {
echo 'trait A::test()';
}
} class b {
use A;
}
$b=new b();
$b->test();
优先级
简单来说 Trait 优先级大于父类方法,但是小于当前类方法。
trait A {
public function test() {
echo 'trait A::test()';
}
public function test1() {
echo 'trait A::test1()';
}
} class base{
public function test(){
echo 'base::test()';
}
public function test1(){
echo 'base::test1()';
}
}
class b extends base{
use A;
public function test(){
echo 'b::test()';
}
}
$b=new b();
$b->test();//b::test()
$b->test1();//trait A::test1()
Trait冲突问题
在使用多个 Trait 时,如果其中存在相同的方法名称,那么就会产生冲突。使用 insteadof 和 as 可以解决方法名称冲突问题
insteadof可以声明使用两个相同方法名称中的具体某个方法。
trait A {
public function test() {
echo 'trait A::test()';
}
}
trait B {
public function test() {
echo 'trait B::test()';
}
}
class c{
use A,B{
A::test insteadof B;//使用 insteadof 明确使用哪个方法
B::test as testB;//使用 as 修改另外一个方法名称,必须在使用 insteadof 解决冲突后使用
}
}
$c=new c();
$c->test();//trait A::test()
$c->testB();//trait B::test()
方法访问控制
使用 as 关键字我们可以对 trait 方法的访问权限进行修改
trait A {
public function test() {
echo 'trait A::test()';
}
private function test1(){
echo 'trait A::test1()';
}
}
class b{
use A{
test as protected;
test1 as public test2;//更改权限时还可以修改名称
}
}
$b=new b();
$b->test();//Fatal error: Call to protected method b::test()
$b->test2();//trait A::test1()
Trait嵌套使用
trait A {
public function test1() {
echo 'test1';
}
} trait B {
public function test2() {
echo 'test2';
}
} trait C {
use A,B;
} class D {
use C;
} $d = new D();
$d->test2(); //test2
变量、属性、方法定义
Trait可定义属性,但类中不能定义同样名称属性
trait A {
public $test1;
} class B {
use A;
public $test;
public $test1;//Strict Standards: B and A define the same property ($test1) in the composition of B...
}
Trait支持抽象方法、支持静态方法、不可以直接定义静态变量,但静态变量可被trait方法引用。
trait A {
public function test1() {
static $a = 0;
$a++;
echo $a;
} abstract public function test2(); //可定义抽象方法
} class B {
use A;
public function test2() { }
} $b = new B();
$b->test1(); //
$b->test1(); //
对比javascript
这种 trait use 的使用方法大概和 javascript 中的 call 有点相似,都是把一个另外一个对象挂载到当前对象的执行环境当中。当然 javascript 是基于原型的语言。两者也没有可比性。仅仅是使用方法相差无几,有助于理解。
function a() {
this.name="a";
this.getName=function(){
console.log(this.name);
}
} function b(){
this.name="b";
a.call(this);
}
var b = new b();
b.getName();//a
因为 javascript 中的变量环境是基于函数的,所以会输出a
php 代码复用机制的更多相关文章
- PHP代码的多继承 -》 PHP代码复用新的姿势 trait
本文参考: http://php.net/language.oop5.traits 一.什么是trait 从PHP 5.4.0 开始 PHP 实现了一种新的代码复用方式 trait. 二.trait ...
- PHP 实现了一种代码复用的方法,称为 trait
自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait. Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制.Trait 为了减少单继承语言的限制,使开发人员能 ...
- Atitit 代码复用的理解attilax总结
Atitit 代码复用的理解attilax总结 1.1. 继承1 1.1.1. 模式1:原型继承1 1.1.2. 模式2:复制所有属性进行继承 拷贝继承1 1.1.3. 模式3:混合(mix-in)1 ...
- Android学习笔记之ListView复用机制
PS:满打满算,差不多三个月没写博客了...前一阵忙的不可开交...总算是可以抽出时间研究研究其他事情了... 学习内容: 1.ListView的复用机制 2.ViewHolder的概念 1.List ...
- cell 的复用机制
一个问题引发的血案,以下是本侦探的探案过程的一部分:以下全部都是转载自别人的博客:http://blog.sina.com.cn/s/blog_9c3c519b01016aqu.html 转自:htt ...
- javascript代码复用模式
代码复用有一个著名的原则,是GoF提出的:优先使用对象组合,而不是类继承.在javascript中,并没有类的概念,所以代码的复用,也并不局限于类式继承.javascript中创建对象的方法很多,有构 ...
- Android AdapterView View的复用机制 分析
对于ListView.GridView相信大家都不陌生,重写个BaseView,实现对于的几个方法,然后就完毕了我们的界面展示.而且在大部分情况下,我们载入特别多的Item也不会发生OOM,大家也都明 ...
- 基于场景解析RecyclerView的回收复用机制原理
最近在研究 RecyclerView 的回收复用机制,顺便记录一下.我们知道,RecyclerView 在 layout 子 View 时,都通过回收复用机制来管理.网上关于回收复用机制的分析讲解的文 ...
- cell的复用机制
以下全部都是转载自别人的博客:http://blog.sina.com.cn/s/blog_9c3c519b01016aqu.html 转自:http://www.2cto.com/kf/201207 ...
随机推荐
- ng4.0 使用[innerHTML]动态插入的富文本如何设置样式
方法一:在css中设置样式 for CSS added to the component :host ::ng-deep mySelector { background-color: blue; } ...
- AndroidのInputFillter之按字符过滤长度,一个中文当两个字符
/** * 以Byte数的方式来实现的LengthFilter * @author bvin */ public class OneByteInputFilter implements InputFi ...
- 如何将Unicode文本写到日志文件中
有时为了定位问题,我们需要结合打印日志来处理.特别是较难复现的,一般都需要查看上下文日志才能找出可能存在的问题.考虑到程序要在不同语言的操作系统上运行,程序界面显示要支持Unicode,打印出来的日志 ...
- 深入web开发之webserver/servlet容器
可能按照书上的demo,自己就能做个小型网站,但是在并发下是什么情况呢?生成了多少对象?对象的关系又是什么?这些问题都要慢慢弄清楚. ------作为后端工程师,不仅要会增删改查,还要了解servle ...
- day_4_25 py
''' 递归: 如果一个函数在内部不调用其它的函数, 而是自己本身的话,这个函数就是递归函数 ''' def factor(num): if num >1: result = num*facto ...
- 基于jdk1.8的HashMap源码学习笔记
作为一种最为常用的容器,同时也是效率比较高的容器,HashMap当之无愧.所以自己这次jdk源码学习,就从HashMap开始吧,当然水平有限,有不正确的地方,欢迎指正,促进共同学习进步,就是喜欢程序员 ...
- Mapper 赋值对应实体属性
public static class MapperExtensions { public static TResult MapTo<TResult>(this object self, ...
- 浅析vue的双向数据绑定
vue 的双向数据绑定是基于es5的 object对象的defineProperty属性,重写data的set和get函数来实现的.1.defineProperty 数据展示 Object.defin ...
- [math] 绘制空间几何体的直观图
这么多年,一直凭着从天而降的神来之灵感画着立体图. 而今才知道在二维平面上绘制空间几何体的直观图也是有方法的.叫做“画法几何” 1. 斜二测图 就是倾斜y轴,使y轴与x轴成45度的夹角.见: http ...
- 读书笔记-iOS核心动画高级技巧
如果不使用+imageNamed:,那么把整张图片绘制到CGContext可能是最佳的方式了. 这里我们利用了CALayer的KVC来存储和检索任意的值,将图层和索引打标签. 使用KVC打标签