【问题标题】:Multiple traits uses same base trait at the same time多个特征同时使用相同的基本特征
【发布时间】:2015-08-12 10:47:06
【问题描述】:

好吧,给出以下条件:

trait Base
{
    public function doSomething()
    {
        // Do fancy stuff needed in other traits
    }
}

trait A
{
    use Base;

    public function foo()
    {
        // Do something
    }
}


trait B
{
    use Base;

    public function bar()
    {
        // Do something else
    }
}

我现在喜欢实现一个使用两个特征 AB 的类:

class MyClass
{
    use A, B;
}

PHP 告诉我它不能重新定义函数doSomething()。 PHP 无法检测到AB 共享一个相同的特征并且不将其复制两次到MyClass 的原因是什么(它是一个错误还是一个阻止我编写不干净代码的功能)?

对于我的问题是否有更好的解决方案,然后是我最终使用的解决方法:

trait Base
{
    public function doSomething()
    {
        // Do fancy stuff needed in other traits
    }
}

trait A
{
    abstract function doSomething();

    public function foo()
    {
        // Do something
    }
}


trait B
{
    abstract function doSomething();

    public function bar()
    {
        // Do something else
    }
}

然后是我的班级:

class MyClass
{
    use Base, A, B;
}

【问题讨论】:

    标签: php traits


    【解决方案1】:

    你可以像这样用“insteadof”解决这个冲突:

    class MyClass
    {
        use A, B {
            A::doSomething insteadof B;
        }
    } 
    

    编辑 解决冲突的更多特征如下所示:

    class MyClass
    {
        use A, B, C, D {
            A::doSomething insteadof B, C, D;
        }
    }  
    

    【讨论】:

    • 感谢您的回答。所以我必须为每个特征写一次?比如当我有特质ABCD我必须写三遍?这对我来说就像是某种“解决方法”......
    • @TiMESPLiNTER 不,只需将它们全部添加,用逗号分隔:use A, B, C, D { A::doSomething insteadof B, C, D; }
    • 我想我会坚持我最初的解决方案。这在我看来比insteadof 解决方案更清楚。因为使用 ABCD 特征的人也可以直接在他们的类中实现 doSomething() 函数,而不是使用 Base 特征(如果需要)。无论如何谢谢。如果没有人会想出另一种解决方案,我会接受这个。
    • @TiMESPLiNTER 很高兴我能帮上忙。当前类的成员会覆盖 Trait 方法。使用insteadof,您可以从类中调用该方法的特征中进行选择——对我来说很清楚。但是,当然,选择你喜欢的任何东西。
    【解决方案2】:

    这已在 PHP 7.3 中得到修复:

    trait A
    {
        public function a(){}
    }
    
    trait B
    {
        use A;
    }
    
    trait C
    {
        use A;
    }
    
    class D
    {
        use B, C;
    }
    

    结果:

    PHP 7.3+ Fine
    PHP ^5|^7.2: Fatal error: Trait method a has not been applied, because there are collisions with other trait methods on D in /in/Z5GTo on line 18
    

    @Grzegorz 的道具发布了指向 PHP 错误的链接,一个答案,但被投票删除。我试图重新打开它,但不能。

    【讨论】:

    • 在 PHP 8 上尝试过,它成功了。在 SO 上寻找验证,我发现的唯一确认是你的帖子。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-15
    • 1970-01-01
    • 1970-01-01
    • 2022-04-26
    • 2011-10-26
    • 2017-09-12
    • 2015-12-04
    相关资源
    最近更新 更多