我想知道这在PHP中是否可行:
trait SomeTrait
{
public function someMethod() { /* ... */ }
}
class Parent
{
use SomeTrait;
}
class Child extends Parent
{
/* Do something to rename someMethod() to someOtherMethod() */
use someMethod as someOtherMethod; // Example
public function someMethod()
{
// Do something different than SomeTrait::someMethod()
}
}
在我的实际用例中, Parent 类是几个子节点的父节点(并且它们实际上都没有使用来自应用于父类的特征的someMethod()
。 Parent类也是外部库的一部分,因此我无法直接修改源代码。
我实际用例中的 Child 类也依赖于 Parent 类的受保护属性,所以我相当确定我需要保留继承。
这实际上是否可行,或者我只是需要处理它,并在相关的 Child 类上使用不同的方法名称?
答案 0 :(得分:3)
如果您只是想覆盖它,那么您在问题中得到的结果应该可以正常工作。根据{{3}}:
优先顺序是当前类的成员覆盖Trait方法,后者又覆盖继承的方法。
如果需要在子类中提供别名,则可以重新use
子类中的特征,利用as
运算符在当前类中定义别名:
class Child extends Foo
{
// This will re-import the trait into your child class, aliasing
// any specified methods.
use SomeTrait {
someMethod as someOtherMethod;
}
public function someMethod() {
$this->someOtherMethod();
}
}
您还可以控制新别名的可见性,例如
use SomeTrait {
someMethod as private someOtherMethod;
}
所有这一切,当你可以打电话时,我真的没有看到这个的好处
parent::someMethod();
在超越它之后。但是如果你有一个特别复杂的继承树,它可能会有用。
此处的完整示例:the manual
答案 1 :(得分:0)
我昨天用以下代码测试了这个: - )
<?php
trait CanWhatever
{
public function doStuff()
{
return 'result!';
}
}
class X
{
use CanWhatever;
public function doStuff()
{
return 'overridden!';
}
}
$x = new X();
echo $x->doStuff();
echo "\n\$x has ";
echo (class_uses($x, 'CanWhatever')) ? 'the trait' : 'no trait';
输出结果为:
overridden!
$x has the trait
因此保持名称相同只是按照正常情况覆盖。
请在此处查看https://3v4l.org/Vin2H