具有冲突方法名称的特征 - 如何使用?
我有一个本质上定义了 getEscapedString() 的接口,它是在几个不同的特征中实现的;实际的班级选择其中之一。这看起来类似于(请原谅拼写错误,因为这只是一个示例,而不是 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()
。有些类会覆盖它以实现自己的风格;但是,此方法不是接口的一部分,因为实现没有它也可以完美运行。
现在需要将其中两个特征组合成一个类(通过连接输出):
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() 的冲突,我可以通过将其添加到 use-clause 中来解决:
Layout_A::getCSS insteadof Layout_B::getCSS;
Layout_A::getCSS as getCSS_Layout_A;
Layout_B::getCSS as getCSS_Layout_B;
现在结果运行良好 < em>除了这两个特征都访问 Layout_A::getCSS
或者 - 如果我覆盖类中的方法 - 这两个特征都访问新的实现。
有没有什么(好的)方法可以让 $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());
}
}
但这确实不好看,而且对于除双重特征之外的该特征的所有用法来说,相当混乱。
I have an interface
in essence defining getEscapedString()
which is implemented in a couple of different traits; the actual classes pick one of them. This looks something similar to (excuse typos as this is just an example and not c/p); similar for Layout_B, Layout_C etc.
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());
}
}
Works fine. Different layout use different abstract methods (rather by fortune), but most of them implement getCSS()
. Some classes overwrite this to implement their own style; however, this method is not part of the interface as an implementation can perfectly live without it.
Now there is the need to combine two of these traits into a single class (by concatenating the output):
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();
}
}
This causes a collision of getCSS() which I could resolve e.g. by adding this into the use-clause:
Layout_A::getCSS insteadof Layout_B::getCSS;
Layout_A::getCSS as getCSS_Layout_A;
Layout_B::getCSS as getCSS_Layout_B;
Now the result runs fine except that both traits access Layout_A::getCSS
or - if I overwrite the method within the class - both traits access the new implementation.
Is there any (nice) way to let $trait::getEscapedString()
use the matching $traig::getCSS()
method? Only way I can think of so far is to change the traits to:
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());
}
}
But this is really not good-looking and rather confusing for all usages of this trait except the double one.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
例如,您有多个类及其实例,
就像特征一样,每个类都以所需的格式输出数据。
现在,如果你想用单个类输出Currency + SimpleImage,你可以这样实现:
For example you have serveral classes and their instances
Like the traits, each of them outputs data in the desired format.
Now if you want to output Currency + SimpleImage with a single class, you could implement it like this: