开发者学堂课程【PHP 进阶教程-由浅入深掌握面向对象开发-第二阶段:Trait 概念】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/712/detail/12701
Trait 概念
内容介绍:
一、学习目标
二、Trait 概念
三、步骤
四、示例
五、小结
一、学习目标
了解 trait 概念和作用,掌握具体的使用方式。
二、trait 概念
Trait: 为类似 PHP 的单继承语言而准备的一种代码复用机制。
1、trait 可以使得单继承语言摆脱为了复用而不得不继承的尴尬,让面向对象变得更加纯粹。
(1)类的继承应该本身类之间具有相似性(包含)。
(2)有些不同类型的类却拥有公共的方法:
①为了实现代码复用就要增加公共类,然后继承(为了继承而继承,不纯粹符合面向对象)。
②提供公共代码让具有共性类引入( trait )。
2、trait 的结构类似于类:可以有属性和方法,但不能有常量。
trait 名字{
# 属性(包含静态)
# 方法(包含静态、抽象方法)
}
3、trait 是为类提供公共方法的,因此是需要在类中引入 trait,从而实现公共内容的使用。
class 类名{
# 引入 trait 即可使用 trait 里定义的内容
use trait 名字;
}
4、一个类可以使用多个 trait。
c1ass 类名{
# 引入 trait 即可使用 trait 里定义的内容
use trait 名字 1,trait 名字2...;
}
三、步骤
1、不同类之间有公共代码,但是类彼此关系不存在继承关系。
2、将公共代码抽离出来存储到 trait 中。
3、在需要使用的类中引入 trait ,实现公共代码复用。
4、如果存在抽象方法,那么引入的类要么是抽象类,要么要实现抽象方法。
四、示例
1、创建 trait。
trait Eat{
}
2.trait 内部可以拥有一个类能拥有成员属性(包含静态),成员方法(包含静态和抽象方法),但不能有类常量。
trait eat{
public $time;
protected $how;
private $info;
public function showTime(){
echo $this->time;
}
protected function showhow(){
echo $this->how;
}
public function abstractMethod();
const PI=3.14;
# 错误: trait 中不能有常量
}
用代码验证一下:
# trait 基本使用
#定义 trait
trait Eat{
public $time;
protected $how;
private $info;
public function showtime(){
echo $this->time;
}
protected function showHow(){
echo $this->how;
}
public function abstractMethod();
# const PI = 3.14;
# 错误: trait 中不能有常量
}
//这个代码显示错误,因为不能有一个对应的抽象。
修改代码:
abstract public function abstractMethod();
//这就是抽象方法,必须用 abstract 关键字,这样系统才能理解改代码是一个抽象方法。
const PI = 3.14;
// trait 中是不能有常量的
如果要实例化:
# const pI = 3.14; # 错误: trait 中不能有常量
}
new Eat();
//显示错误,不能实例化 trait , trait 不允许实例化。
所以 trait 只是单纯的为类提供一些公共的内容。
3、trait 是用来实现代码的复用的,不可以被实例化也不可以被继承(不是类)。
trait Eat{}
new Eat();
# 错误,没有该类
4、trait 是用来将公共代码提供给其他类使用的,而类要使用 trait 的前提是加载对应的 trait 。
trait Eat{
Public function show(){
echo 'eat';
}
}
# 类中加载 trait
class Human{
# 加载:使用 use 关键字
use Eat;
#use 就表示将 trait Eat 中的所有东西拿到了当前类 Human 中
}
# 使用 trait 中的内容
$h=new Human();
$h->show();
# eat: Human 类自己没
show 方法,但是因为使用了 trait Eat,所以可用
将前面代码的注释,写代码如下:
trait Eat{
public function show(){
echo 'eat';
}
}
#类中使用
class Human{
#引入 trait
use Eat;
}
class Animal{
# 引入 trait
use Eat;
}
//通过这个代码,发现不需要将 eat 抽象出来。
之后实例化类,然后调用从 eat 里面获取到的公共代码。
代码:
#实例化类
$h = new ! Human();
$h->show();
//如果还有更多的共性,可以将共性的东西抽到一个地方,只要引入对应的 trait 即可。引入之后,子类都可以应用继承里面的内容。
5、一个类可以使用多个 trait 。
trait t1{
public function eat(){
echo 'eat';
}
}
trait t1{
public function sleep(){
echo 'sleep';
}
}
class Human{
# 使用多个 trait
use tl,t2;
public function show(){
$this->eat();
$this->s1eep();
}
}
$h=new Human();
$h->show();
# eat sleep
//上述代码为 trait 的使用调用的过程。
代码:
public function show(){
$this->eat();
$this->s1eep();
}
//当然也可以在这个方法里面,类里面自己制定方法,实现调用,用 $this 调用即可。因为 use tl,t2; 就相当于把代码:
public function sleep(){
echo 'sleep';
}
里面的内容放到此处。
五、小结
Trait 是用来解决有公共需求但是不属于同一类型里的代码复用问题(解决 PHP 单一继承问题)。
为了让面向对象的继承更加纯粹(符合继承关系)。
为了让代码的复用性变得更加强大。