特性冲突解决以及不断变化的可见性

Traits conflict resolution together with changing visibility

假设我们有 2 个特征(在 PHP 7.1 中测试):

<?php

trait HelloA
{
    private function X()
    {
        echo "x";
    }
}

trait HelloB
{
    private function X()
    {
        echo "y";
    }
}

如果我们想应用任何特征并创建方法 X public 我们可以这样定义 class:

class Summary
{
    use HelloA {
        HelloA::X as public;
    }
}

然后就可以正常使用了

$s = new Summary();
$s->X();

而且没有任何问题。

但是如果我们想同时使用这两个特征并像这样定义摘要class:

class Summary
{
    use HelloA, HelloB {
        HelloA::X as public;
    }
}

我们将收到致命错误:

Trait method X has not been applied, because there are collisions with other trait methods on Summary.

我们可以这样解决定义class的冲突:

class Summary
{
    use HelloA, HelloB {
        HelloA::X insteadof HelloB;
    }
}

但现在不可能运行

$s = new Summary();
$s->X();

更多,因为我们会得到致命错误:

Fatal error: Uncaught Error: Call to private method Summary::X() from context ''

问题是 - 摘要 class 中是否有任何方法既可以解决冲突又可以更改方法可见性?

目前我认为这是不可能的,例如这样的构造:

use HelloA, HelloB {
        HelloA::X insteadof HelloB as public;
    }

会导致解析错误,但也许应该以其他方式编写才能使其正常工作?

显然,作为解决方法,我们可以在 Summary class 中创建不同的方法名称和 运行 X 方法,但这不是我要问的:)

当然,您可以同时更改方法可见性和解决冲突,只是不在同一语句中。

class Summary
{
    use HelloA, HelloB {
        HelloA::X insteadof HelloB;
        HelloA::X as public;
    }
}

这应该完全符合您的期望。