具有冲突方法名称的特征 - 如何使用?
traits with colliding method names - how to work with?
我有一个 interface
本质上定义了 getEscapedString()
它是在几个不同的特征中实现的;实际 classes 选择其中之一。这看起来类似于(请原谅打字错误,因为这只是一个例子,而不是 c/p);类似于 Layout_B、Layout_C 等
trait Layout_A {
abstract protected function getUnescapedString() : String;
protected function getCSS() : ?String {
return NULL;
}
public function getEscapedString() : String {
echo sprintf('<td class="%s">%s</td>', $this->getCSS(), $this->getUnescapedString());
}
}
工作正常。不同的布局使用不同的抽象方法(而不是靠运气),但大多数实现getCSS()
。一些 classes 覆盖它以实现他们自己的风格;但是,此方法不是接口的一部分,因为没有它实现也可以完美地存在。
现在需要将这些特征中的两个组合成一个 class(通过连接输出):
class DoubleOutput {
use Layout_A, Layout_B {
Layout_A::getEscapedString as getEscapedString_Layout_A;
Layout_B::getEscapedString as getEscapedString_Layout_B;
}
public function getEscapedString() : String {
echo getEscapedString_Layout_A();
echo getEscapedString_Layout_B();
}
}
这会导致 getCSS() 发生冲突,我可以解决这个问题,例如通过将其添加到使用子句中:
Layout_A::getCSS insteadof Layout_B::getCSS;
Layout_A::getCSS as getCSS_Layout_A;
Layout_B::getCSS as getCSS_Layout_B;
现在结果运行良好 除了 这两个特征都访问 Layout_A::getCSS
或者 - 如果我覆盖 class 中的方法 - 这两个特征都访问新的实施。
有什么(好的)方法可以让$trait::getEscapedString()
使用匹配的$traig::getCSS()
方法吗?到目前为止我能想到的唯一方法是将特征更改为:
trait Layout_A {
abstract protected function getUnescapedString() : String;
protected function getCSS_Layout_A() : ?String {
return NULL;
}
public function getEscapedString() : String {
echo sprintf('<td class="%s">%s</td>', $this->getCSS_Layout_A(), $this->getUnescapedString());
}
}
但这真的不好看,而且除了双重之外,这个特征的所有用法都很混乱。
例如,您有多个 classes 及其实例
class Layout_Currency;
class Layout_SimpleImage;
...
$layout_currency = new Layout_Currency();
$layout_simpleimage = new Layout_SimpleImage();
...
与特征一样,它们中的每一个都以所需的格式输出数据。
现在如果你想用单个 class 输出 Currency + SimpleImage,你可以这样实现:
class DoubleOutput {
public function getEscapedString(){
global $layout_currency, $layout_simpleimage;
$layout_currency->getEscapedString();
$layout_simpleimage->getEscapedString();
}
}
我有一个 interface
本质上定义了 getEscapedString()
它是在几个不同的特征中实现的;实际 classes 选择其中之一。这看起来类似于(请原谅打字错误,因为这只是一个例子,而不是 c/p);类似于 Layout_B、Layout_C 等
trait Layout_A {
abstract protected function getUnescapedString() : String;
protected function getCSS() : ?String {
return NULL;
}
public function getEscapedString() : String {
echo sprintf('<td class="%s">%s</td>', $this->getCSS(), $this->getUnescapedString());
}
}
工作正常。不同的布局使用不同的抽象方法(而不是靠运气),但大多数实现getCSS()
。一些 classes 覆盖它以实现他们自己的风格;但是,此方法不是接口的一部分,因为没有它实现也可以完美地存在。
现在需要将这些特征中的两个组合成一个 class(通过连接输出):
class DoubleOutput {
use Layout_A, Layout_B {
Layout_A::getEscapedString as getEscapedString_Layout_A;
Layout_B::getEscapedString as getEscapedString_Layout_B;
}
public function getEscapedString() : String {
echo getEscapedString_Layout_A();
echo getEscapedString_Layout_B();
}
}
这会导致 getCSS() 发生冲突,我可以解决这个问题,例如通过将其添加到使用子句中:
Layout_A::getCSS insteadof Layout_B::getCSS;
Layout_A::getCSS as getCSS_Layout_A;
Layout_B::getCSS as getCSS_Layout_B;
现在结果运行良好 除了 这两个特征都访问 Layout_A::getCSS
或者 - 如果我覆盖 class 中的方法 - 这两个特征都访问新的实施。
有什么(好的)方法可以让$trait::getEscapedString()
使用匹配的$traig::getCSS()
方法吗?到目前为止我能想到的唯一方法是将特征更改为:
trait Layout_A {
abstract protected function getUnescapedString() : String;
protected function getCSS_Layout_A() : ?String {
return NULL;
}
public function getEscapedString() : String {
echo sprintf('<td class="%s">%s</td>', $this->getCSS_Layout_A(), $this->getUnescapedString());
}
}
但这真的不好看,而且除了双重之外,这个特征的所有用法都很混乱。
例如,您有多个 classes 及其实例
class Layout_Currency;
class Layout_SimpleImage;
...
$layout_currency = new Layout_Currency();
$layout_simpleimage = new Layout_SimpleImage();
...
与特征一样,它们中的每一个都以所需的格式输出数据。
现在如果你想用单个 class 输出 Currency + SimpleImage,你可以这样实现:
class DoubleOutput {
public function getEscapedString(){
global $layout_currency, $layout_simpleimage;
$layout_currency->getEscapedString();
$layout_simpleimage->getEscapedString();
}
}