Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中基于对象属性值动态实现接口?_Php_Oop_Architecture_Object Oriented Analysis_System Design - Fatal编程技术网

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

在PHP中基于对象属性值动态实现接口?,php,oop,architecture,object-oriented-analysis,system-design,Php,Oop,Architecture,Object Oriented Analysis,System Design,假设我们有一个Dog类和一个Category类,狗可以分配给它们 class Dog { function categories() {} // Return the categories of the dog. } class Category { function dogs() {} // Return the dogs under this category. } 狗可以有“宠物”和“牧羊人”两类。当被分配到“宠物”类别时,它是“宠物狗”,而“牧羊人”也是如此 宠物狗和

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

class Dog {
    function categories() {} // Return the categories of the dog.
}

class Category {
    function dogs() {} // Return the dogs under this category.
}
狗可以有“宠物”和“牧羊人”两类。当被分配到“宠物”类别时,它是“宠物狗”,而“牧羊人”也是如此

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

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

interface-Huggable{
函数hug();
}
可培训的接口{
函数列();
}
理想情况下,当一只狗被分配到“宠物”类别时,它会实现
Huggable
界面,如果它被分配到“牧羊人”类别,它会实现
trainiable
类别


有可能吗?

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

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

愚蠢的做法:

你将有一个需要装饰的班级:

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;

    }
}
您的界面,
Trainable
Huggable

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;
}
一个实现Trainable并将特定类别添加到装饰实例的装饰器:

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";
    }
}
另一个
FluffyDecorator
实现了
Huggable

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;
    }
}
最后,您可以这样使用它:

$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
)
 */

“狗”和“类别”之间的多对多关系由你们决定。这是一个单独的问题,可以用许多不同的方法处理。

PHP不允许动态混合类。这可能是一个很好的用途,谢谢!我最近刚接触oop,我了解oop的功能和清洁度。这篇文章有助于我理解如何扩展工作。干得好,先生!