开发者学堂课程【PHP 进阶教程-由浅入深掌握面向对象开发-第二阶段:Trait 代码复用总结】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/712/detail/12705
Trait 代码复用总结
主要内容
一、总结
一、总结
1、trait 是一种类似于 class 的关键字,但是产生出来的东西不能被实例化,它可以拥有类的所有成员结构的属性方法,但是类常量除外,其他的都可以有,包括抽象方法,但是如果把抽象方法引入到类里面,类必须要对它进行实现。
2、trait 的本质是用来实现代码复用,为其他类提供公共代码的,所以其他类如果要用 trait ,使用 use 关键字,把它引入进去就可以了。
3、在类中 use 具体 trait 就相当于在 trait 内的所有的代码在类里面又写了一遍,把它复制过去放到里面。
4、一个类可以使用多个 trait ,但是要注意它的同名问题。注意:属性不允许同名,但是方法同名,要考虑怎么去用。
(1)如果多个 trait 里面有同名的,只要把其中一个用 insteadof 替代就可以了,但是整个类里面只能访问替代的这个。
(2)如果想要访问两个,都用 insteadof 替代之后再使用 as 制作方法别名。
5、类中引入 trait 之后,要注意同名成员问题。
(1)同名属性:不允许(除非同名同值,同名同值就相当于定义一个就够了,所以一般在这个 trait 里面比较少用这种属性)
(2)同名方法:允许,就是类里面的方法这种会覆盖 trait 里面的方法。
如果是多个 trait 里面出现同名,同时被引入,那就需要考虑到前面的这种替代或者别名的问题去解决。
6、如果类在使用 trait 同时本身还继承了其他的类,里面就会涉及优先级的问题,子类是高于 trait , trait 高于父类。如果要使用父类都是使用 parent 关键字,如果子类父类 trait 里面都出现了同名,也就相当于完全重写,那么 trait 中使用别名后,方法才能用,负责用不了。
7、类在使用 trait 的时候可以修改 trait 的控制级别,可以更严或者更宽松。
(1)直接修改(限定的是方法本身,这种应用较多):[trait名::]+方法名 +as 访问修饰限定符(会让引入类只有一个方法名,因为只是改了它的权限,而这个权限就是最终的权限);
(2)通过别名:[trait 名::](有没有都可以,如果是单个或者没有重复的就是方法名)+方法名+ as 访问修饰限定符+别名(会让引入类有两个方法,一个是 trait 本身方法(不会被修改),另一个是别名(是最终修改的权限)。
8、trait 中可以使用抽象方法,使用 trait 的类必须为抽象类或者抽象方法。举例如下:
trait t{
abstract public function eat();
}
# 抽象类
abstract class Human{
use t;
//抽象类可直接使用抽象方法
}
# 实现类
class Animal{
use t;
# 实现 t 中的抽象方法
public function eat(){ }
// 本质相当于把原来的东西覆盖掉了
}
所以一般只有抽象类才会引入 trait 中的抽象方法,实体的一般就会引入一些已经解决好的 trait 。
9、 trait 使用机制
(1)有公共代码要实现(方法居多),公共代码就是有多个类型的类使用同一个代码,就把这些东西提出来放到 trait 中;
(2)公共代码不是属于某一类事物特有,而是很多事物都有(不符合继承)。 trait 提出的特点就是因为那些类没有办法去实现继承关系,如果要非继承也行,但它继承了之后,会让面向对象变得不那么规范,不那么纯粹,让这种继承方式变得不那么能说得过去,所以这个时候才会去使用 trait 机制。
整体上讲,trait 机制在项目开发里面,目前使用还是偏少,但是这个不影响后面它是否会发扬光大。