Den*_*nis 5 php oop polymorphism dynamic-typing
我有一个名为Assembly隐藏底层产品实现的类.  ProductA可以有一套吸气剂,ProductB可以有另一套吸气剂.  
虽然PHP非常宽容,如果我不混淆产品和吸气剂,我的代码会起作用,但是当我搞砸并填充Assembly时ProductA,没有提供保护,但是后来使用了getter ProductB.
此外,我的IDE确实知道来自任何一个类的方法,因此当我Assembly使用其中任何一个的getter 工作时,没有提供自动完成Product.
我想要更多的防弹代码,一个Assembly 知道或知道Product它当前托管哪个子类型的代码.有办法吗?
以下示例
class Assembly
{
    private $product;
    public function setProduct(Product $product) {
        $this->product = $product;
    }
    public function getA() {
        return $this->product->getA();
    }
    public function getB() {
        return $this->product->getB();
    }
}
class Product { }
class ProductA extends Product
{
    public function getA() {
        return "A";
    }
}
class ProductB extends Product
{
    public function getB() {
        return "B";
    }
}
//set assembly
$assembly = new Assembly();
//define product sub-type
$product = new ProductB();
//place product into assembly
$assembly->setProduct($product);
//assembly has no clue which subtype it has 
print $assembly->getB(); // "B"
print $assembly->getA(); // prints nothing
接口建议
interface CompositeProductInterface
{
    public function getA();
    public function getB();
}
//update code in Assembly to:
public function setProduct(CompositeProductInterface $product)
{
    $this->product = $product;
}
这让我在我的IDE中自动完成,这很好,但不能解决我的其他问题.此外,我将一些东西拼凑成一个单一的"复合"产品有点怪异......这看起来更像是一种解决方法.在我的具体情况下,我有两个非常相似的产品,在一些微小的东西,如一些属性上有所不同.
真实世界的例子
产品型号A和B都有一个工程图,其中列出了用于识别各种产品尺寸的变量.两种产品的命名尺寸相似.例如,产品A上的M1表示产品B上的相同物理尺寸.但是,产品A具有产品B上不存在的特征,反之亦然.
如果仍然感觉太假设,实际图纸上的实际尺寸列为B2和B3.这些尺寸(B2,B3)不存在于其他产品型号上.我希望能够使用汇编构造列出图形上的变量,包括M1,B2,B3等.我可以这样做
print $assembly->getM1(); //works for both products
print $assembly->getB2(); //works for one product only
print $assembly->getB3(); //same as above
目标
目标是让一个类(程序集)负责列出命名维度变量,每个产品只知道自己.所以
我认为这不是正确的解决方案,但您所要求的可以通过以下方式实现。
get_class($product);
会告诉你$product是哪个班级。这将导致以下代码:
private $product;
private $productClass;
public function setProduct(Product $product) {
    $this->product = $product;
    $this->productClass = get_class($product);
}
或者:
public function getProductClass(){
    return get_class($this->$product);
}
这可能会导致类似于以下内容的检查:
public function getA() {
    if($this->productClass === "ProductA")
        return $this->product->getA();
}
正如以下文献中所记载的: