多重继承,'需要'扩展两个类

时间:2017-01-24 11:07:26

标签: php

假设我们在\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>

1 个答案:

答案 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似乎不允许任何其他机制实现这一点,我对任何其他想法持开放态度。