-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Description
PHP 类和对象之 Trait
Trait 文档
PHP 仅支持单继承(即仅能继承 extends 一个父类),Trait 功能提供类似于多继承的功能
Trait 定义和使用与 clss 相同,只不过声明关键字用 trait 而非 class,另外 trait 不能实例化
优先级
当前类、基类和 Trait 存在相同方法时的优先级关系如下:
当前类方法 > Trait > 基类
使用 Trait
在类声明内使用关键字 use 引入 Trait
<?php
trait A
{
}
trait B
{
}
class Test
{
use A, B;
}Trait 语法特性
- 可以定义 abstract 方法
- 支持静态属性和方法
- 支持静态成员
- 使用 trait 的类,不能定义与 trait 内定义的同名属性(fatal error)
但如果可见性及初始值相同的属性可以定义即属性兼容
冲突解决和别名
- 两个Trait 有相同方法的冲突解决: 在当前类中使用
insteadof操作符指明使用哪个方法 - 为 Trait 中的方法声明别名:在当前类中使用
as引入别名,此时会在当前类中存在别名方法和 Trait 中定义的方法
<?php
trait A
{
public function hi()
{
echo 'hi from A' . PHP_EOL;
}
}
trait B
{
public function hi()
{
echo 'hi from B' . PHP_EOL;
}
}
class Test
{
use A, B {
//指明实例调用 hi() 方法使用 Trait A 中的 hi() 而非 Trait B 中的 hi()
A::hi insteadof B;
// 在当前类引入 hi 的别名方法 sayHi, 也可以声明别名方法的访问权限
A::hi as /*protected*/ sayHi;
//将 Trait B 中的 hi 引入 hello 的别名
B::hi as hello;
}
}
$test = new Test();
$test->hi();
$test->sayHi();
$test->hello();
// var_dump(get_class_methods('Test'));
// print:
// array(3) {
// [0]=>
// string(5) "sayHi"
// [1]=>
// string(2) "hi"
// [2]=>
// string(5) "hello"
// }