假设我们在\Base\Form\
命名空间中有两个类:
class Field {
protected $name;
protected $value;
}
class DropdownField extends Field {
protected $options = [];
// with functions like setOptions(), addOption(), removeOption() etc.
}
现在,在另一个命名空间中,存在一个在Field
上扩展的类,它具有额外的'layout_position'
属性:
namespace Integrations;
class IntegrationsField extends \Base\Form\Field {
const LAYOUT_POSITION_LEFT = 'left';
const LAYOUT_POSITION_RIGHT = 'right';
protected $layoutPosition = self::LAYOUT_POSITION_LEFT;
}
现在,你可能会看到这一个,但如果IntegrationsField
也可以是下拉列表:
namespace Integrations;
class IntegrationsDropdownField extends \Base\Form\DropdownField {}
当然,这个也应该有$layoutPosition
,它应该继承自IntegrationsField
,但是因为我们不能扩展两个类,所以最好的解决方案是什么?< / p>
答案 0 :(得分:5)
PHP不支持多重继承。但是,您可以使用特征来重写逻辑,以(模拟)模拟它。
class Field {
protected $name;
protected $value;
}
trait Dropdown {
protected $options = [];
// with functions like setOptions(), addOption(), removeOption() etc.
}
interface IntegrationPositions {
const LAYOUT_POSITION_LEFT = 'left';
const LAYOUT_POSITION_RIGHT = 'right';
}
trait Integration {
protected $layoutPosition = IntegrationPositions::LAYOUT_POSITION_LEFT;
}
class DropdownField extends Field {
use Dropdown;
}
class IntegrationField extends Field {
use Integration;
}
class DropdownIntegrationField extends Field {
use Integration,Dropdown;
}
更新:由于@Adambean注意到traits不能有常量。因此,我使用枚举更新了示例。
我觉得奇怪的是必须声明一个特征是内部的特征,但据我所知,PHP似乎不允许任何其他机制实现这一点,我对任何其他想法持开放态度。