特性冲突解决以及不断变化的可见性
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;
}
}
这应该完全符合您的期望。
假设我们有 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;
}
}
这应该完全符合您的期望。