首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHP中基于对象属性值的动态接口实现?

PHP中基于对象属性值的动态接口实现?
EN

Stack Overflow用户
提问于 2018-09-11 15:26:01
回答 1查看 912关注 0票数 2

假设我们有一个Dog类和一个可以分配给狗的Category类。

代码语言:javascript
复制
class Dog {
    function categories() {} // Return the categories of the dog.
}

class Category {
    function dogs() {} // Return the dogs under this category.
}

狗可以有‘宠物’和‘牧羊人’类别。当被分配到“宠物”类别时,它是“宠物狗”,“牧羊人”也是如此。

宠物犬和牧羊犬具有不同的属性和功能。然而,狗既可以是“宠物狗”,也可以是“牧羊犬”。

我可以想象“宠物狗”和“牧羊犬”有不同的界面。

代码语言:javascript
复制
interface Huggable {
    function hug();
}

interface Trainable {
    function train();
}

理想情况下,当狗被分配到‘宠物’类别时,它实现了Huggable接口,如果它被分配给‘牧羊人’类别,它实现了Trainable类别。

有可能吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-11 17:43:14

正如我所评论的,本机不可能用PHP实现这一点。

但是您可以使用装饰器来实现一些东西,例如。

一种愚蠢的装潢工方法:

你会有你要去装饰的班级:

代码语言:javascript
复制
class Animal {

    protected $categories = [];

    public function getCategories() {
        return $this->categories;
    }

    public function addCategory( string $category ) {
        // we should check the animal doesn't already belong to this category
        $this->categories[] = $category;

    }
}

您的接口,TrainableHuggable

代码语言:javascript
复制
interface Trainable {

    function train();
}

interface Huggable {
    // see https://github.com/php-fig/fig-standards/blob/master/proposed/psr-8-hug/psr-8-hug.md
    function hug() : bool;
}

一个实现可培训的装饰器,并将特定类别添加到装饰实例中:

代码语言:javascript
复制
class PetDecorator extends Animal implements Trainable {


    public function __construct( Animal $animal ) {

        $this->categories = $animal->getCategories();
        $this->addCategory('pet');

    }

    public function train() {
        echo "I'm housebroken!\n";
    }
}

和另一个实现FluffyDecoratorHuggable

代码语言:javascript
复制
class FluffyDecorator extends Animal implements Huggable {

    public function __construct( Animal $animal ) {

        $this->categories = $animal->getCategories();
        $this->addCategory('loveBear');
    }

    public function hug( ) :bool {
        echo "Much hug!\n";
        return true;
    }
}

最后,您可以这样使用它:

代码语言:javascript
复制
$fido    = new Animal();
$fidoPet = new PetDecorator($fido);

$fidoPet->train();
// I'm housebroken!

print_r($fidoPet->getCategories());
/*
Array
(
    [0] => pet
)
*/

$fidoLove = new FluffyDecorator($fidoPet);
// Much hug!
$fidoLove->hug();

print_r($fidoLove->getCategories());
/*
 Array
(
    [0] => pet
    [1] => loveBear
)
 */

我把“狗”和“类别”之间的多对多关系留给你。这是一个单独的问题,可以用许多不同的方式来处理。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52279380

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档