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 >%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 >%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.
CodePudding user response:
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();
}
}