假设我们有一个Dog
类和一个Category
类,可以将狗分配给它们。
class Dog {
function categories() {} // Return the categories of the dog.
}
class Category {
function dogs() {} // Return the dogs under this category.
}
狗可以具有“宠物”和“牧羊人”类别。分配给“宠物”类别时,它是“宠物狗”,“牧羊人”也是如此。
宠物狗和牧羊犬具有不同的属性和功能。但是,狗既可以是“宠物狗”又可以是“牧羊犬”。
我可以想象,例如“宠物狗”和“牧羊犬”具有不同的界面
interface Huggable {
function hug()
}
interface Trainable {
function train()
}
理想情况下,当狗被分配到“宠物”类别时,它会实现Huggable
接口;如果狗被分配到“牧羊人”类别,则它会实现Trainable
类别。
有可能吗?
答案 0 :(得分:1)
正如我评论的那样,不可能用PHP本机实现。
例如,您可以使用装饰器来实现某些东西。
一种愚蠢的decorator方法:
您将有待装饰的课程:
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
的{{1}}
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;
}
}
“狗”和“类别”之间的多对多关系由您自己决定。那是一个单独的问题,可以通过许多不同的方式来处理。