我可以只从特征中导入一些选定的方法吗?

Can I import only some selected methods from a trait?

如果一个特征包含多个属性和方法,我可以只导入其中的几个吗?

trait MyTrait
{
    public function ok()
    {
        echo 'ok';
    }

    public function nope()
    {
        echo 'not ok';
    }
}

class MyClass
{
    use MyTrait {
        MyTrait::ok as ok;
    }
}

$mc = new MyClass;

$mc->ok(); // This should work
$mc->nope(); // This shouldn't work

问题是我正在开发包并想从另一个包中导入几个方法(以确保某些操作以相同的方式工作)。但是这些方法的特征包含 11 个属性和 76 个方法。我不希望所有这些污染我的命名空间。

有没有选择性导入的方法?还是我必须退回到一些反思技巧?

据我所知,你不能那样做。使用特征基本上将其内容包含在 class 中。它定义的属性和方法很可能相互依赖。

另一种选择是在不包含特征的 class 中手动定义所需的方法,而是将调用委托给包含特征的 class 实例。

像这样:

trait MyTrait
{
  public function ok(): void
  {
    echo 'ok';
  }

  public function nope(): void
  {
    echo 'not ok';
  }
}

class MyTraitDelegate
{
  use MyTrait;
}

class MyClass
{
  private MyTraitDelegate $traitDelegate;

  public function __construct()
  {
    $this->traitDelegate = new MyTraitDelegate();
    // Note: you could also inject it, but in this case, not sure it's worth.
  }

  public function ok(): void
  {
    $this->traitDelegate->ok();
  }
}

$mc = new MyClass;

$mc->ok();   // works
$mc->nope(); // method not found

另一种选择是将您不想要的方法私有化:

class MyClass1 {
    use HelloWorld { sayHello as protected; }
}

另请参阅:https://www.php.net/manual/en/language.oop5.traits.php

它说它不能更改为私有,但我发现它对我有效...