具有冲突方法名称的特征 - 如何使用?

发布于 2025-01-12 02:12:58 字数 1755 浏览 1 评论 0原文

我有一个本质上定义了 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

下雨或天晴 2025-01-19 02:12:58

例如,您有多个类及其实例,

class Layout_Currency;
class Layout_SimpleImage;
...

$layout_currency = new Layout_Currency();
$layout_simpleimage = new Layout_SimpleImage();
...

就像特征一样,每个类都以所需的格式输出数据。

现在,如果你想用单个类输出Currency + SimpleImage,你可以这样实现:

class DoubleOutput {
    public function getEscapedString(){
         global $layout_currency, $layout_simpleimage;
         $layout_currency->getEscapedString();
         $layout_simpleimage->getEscapedString();
    }
}

For example you have serveral classes and their instances

class Layout_Currency;
class Layout_SimpleImage;
...

$layout_currency = new Layout_Currency();
$layout_simpleimage = new Layout_SimpleImage();
...

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:

class DoubleOutput {
    public function getEscapedString(){
         global $layout_currency, $layout_simpleimage;
         $layout_currency->getEscapedString();
         $layout_simpleimage->getEscapedString();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文