问题
I have searched for solutions to the diamond problem but the only one I have found is using traits which I can't use in my case, so I'm asking here to see if anyone has an alternative solution.
I have a base class Controller
(I cannot change this class) and have two subclasses SecurityController
and DevController
. Each of these subclasses introduces methods which also use methods inside the base class. I then have a final class ApplicationController
which, ideally, would extend both SecurityController
and DevController
. Of course, this isn't possible in PHP (single inheritance only).
So my question becomes - what would be the best way to resolve this? I came across traits but then realised that doesn't work as the 2 subclasses (which I thought might suit traits) both need to extend Controller
to access methods inside it. The only other alternative I can see is forcing SecurityController
to extend DevController
(or vice versa). Although this works it is not ideal as these two classes come from separate modules which I was hoping to create as a drop in and use as is type of plugin.
This post on code review looks promising. An alternative would be good though - I feel I'm likely to introduce errors when trying to improve upon that code.
Note about the solution
The accepted answer is still the best way I have found to resolve this issue in general. However, in this case I was able to use traits. I had a method in SecurityController
called beforeExecute($dispatcher)
- by changing it to beforeExecuteTrait($controller, $dispatcher)
and making SecurityController
a trait then having ApplicationController
extend Controller
, use SecurityController
and adding a method in ApplicationController
as
public function beforeExecute($dispatcher)
{
return $this->beforeExecuteTrait($this, $dispatcher);
}
and by applying the same logic to DevController
I achieved the desired behaviour.
回答1:
It sounds like you could benefit from dependency injection. In other words, you would instantiate the other classes and then inject those instances into your main class for you to use. This avoids any messes with inheritance in PHP.
class A extends B {
}
class C {
/** @var \A */
protected $classa;
public function __construct(\A $class) {
$this->classa = $class;
}
}
$a = new \A();
$c = new \C($a);
来源:https://stackoverflow.com/questions/32188850/how-to-resolve-the-diamond-issue-in-php