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

Mav*_*ave 2 php

假设我们在\Base\Form\命名空间中有两个类:

class Field {
    protected $name;
    protected $value;
}

class DropdownField extends Field {
    protected $options = [];
    // with functions like setOptions(), addOption(), removeOption() etc.
}
Run Code Online (Sandbox Code Playgroud)

现在,在另一个命名空间中,存在一个扩展的类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;
}
Run Code Online (Sandbox Code Playgroud)

现在,您可能会看到这一个即将到来,但如果IntegrationsField这也可以是下拉列表:

namespace Integrations;
class IntegrationsDropdownField extends \Base\Form\DropdownField {}
Run Code Online (Sandbox Code Playgroud)

当然,这个也应该有$layoutPosition,应该继承IntegrationsField,但由于我们不能扩展两个类,这里​​最好的解决方案是什么?

apo*_*fos 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;
}
Run Code Online (Sandbox Code Playgroud)

更新:由于@Adambean注意到traits不能有常量.因此,我使用枚举更新了示例.

如果必须声明一个特征内部的枚举,那就觉得很奇怪,但据我所知,PHP似乎不允许任何其他机制实现这一点,我对任何其他想法持开放态度.

  • 接口可以有常量吗?我希望我在9小时前知道.:d (2认同)