PHP中traits的特性及用法
分类: 后端开发
2023-12-06
浏览: 122
评论: 0
字数: 17893

自5.4.0版本开始,PHP 实现了一种代码复用的方法,称为trait

Trait由来

php是一种单继承语言,为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method,于是就有了trait特性。

单继承语言缺陷

单继承语言缺陷说明:

缺陷名称 缺陷描述
单继承限制 在单继承语言中,一个类只能继承自一个父类。这意味着,如果需要复用多个类的功能,就需要创建一个新的父类来包含这些功能,然后让需要复用这些功能的类继承自这个新的父类。这种方式可能会导致代码的复杂度增加,并且不利于代码的维护和扩展。
代码重复 在单继承语言中,如果需要复用多个类的功能,可能需要在不同的子类中重复实现这些功能。这可能会导致代码的重复,增加了代码的维护成本。
灵活性不足 在单继承语言中,子类只能继承父类的公有成员,而不能继承父类的私有成员。这意味着,如果需要复用父类的私有成员,就需要将这些私有成员公开,这可能会破坏类的封装性,降低代码的可维护性。
难以扩展 在单继承语言中,如果需要在子类中添加新的功能,可能需要修改父类的代码。这可能会导致代码的不稳定性,并且不利于代码的扩展。

Trait使用案例

Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。

php
<?php
// 定义一个`Hello` trait,用于输出`Hello`字符串。
trait Hello {
    public function sayHello() {
        echo 'Hello ';
    }
}

// 定义一个`World` trait,用于输出`World`字符串。
trait World {
    public function sayWorld() {
        echo 'World';
    }
}

// 定义一个`MyHelloWorld`类,使用`Hello`和`World` trait,输出`Hello World!`字符串。
class MyHelloWorld {
    use Hello, World;
    public function sayExclamationMark() {
        echo '!';
    }
}

$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
$o->sayExclamationMark();
// 输出“Hello World!”
?>

Trait的使用问题

在php8.3以下版本中,Trait中的静态属性不会覆盖父类中的静态属性issues

php
<?php
trait Singleton
{
    protected static $instance = null;

    public static function getInstance(...$args)
    {
        if(!isset(self::$instance)){
            self::$instance = new static(...$args);
        }
        return self::$instance;
    }
}

class A
{
    use Singleton;

    public function getB()
    {
        return B::class::getInstance();
    }
}

class B extends A
{
    use Singleton;
}
var_dump(A::getInstance()->getB()); // 输出:A,实际应该输出:B

Trait的优劣

  • Trait无法通过自身来实例化。
  • Trait它为传统继承增加了水平特性的组合,使用它的类,不需要继承。只需要 use 引入。
  • TraitClass相似,但仅仅旨在用细粒度和一致的方式来组合功能。
点赞
打赏
本文标签:
php
本文链接:
版权声明:
本文由vscing原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权