php - 使用多态时,如何让 PHP 代码知道传递给它的特定类子类型?

标签 php oop polymorphism dynamic-typing

关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。












想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。

6年前关闭。




Improve this question




我有一个类(class)叫 Assembly隐藏了底层产品的实现。 ProductA可以有一组 setter/getter ,ProductB可以有另一个。

虽然 PHP 非常宽容,如果我不混淆 Products 和 getter,我的代码将可以工作,但是当我搞砸并填充时没有提供保护 AssemblyProductA ,然后使用来自 ProductB 的 setter/getter .

此外,我的 IDE 确实知道任一类的方法,因此当我在 Assembly 中工作时没有提供自动完成功能。来自 Product 的 setter/getter .

我想要更多的防弹代码,一个在哪里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)建议
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

目标

目标是让一个类(程序集)负责列出命名维度变量,并且每个产品只知道自己。所以
  • 程序集说“我知道我想列出的命名变量(M1、B2、B3)的所有信息,无论产品型号如何”
  • 产品 A 说“我只知道我包含什么。我包含命名维度 A。我不知道 B 是什么,我也不关心
  • 产品 B 说“我只知道 B”
    ...
  • 最佳答案

    我不认为这是正确的解决方案,但是您可以通过以下方式实现您的要求。

    get_class($product);
    

    会告诉你哪个类(class)$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();
    }
    

    也记录在:

    http://php.net/manual/en/function.get-class.php

    关于php - 使用多态时,如何让 PHP 代码知道传递给它的特定类子类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33677793/

    相关文章:

    php - 用PHP加密的openssl需要用Ruby解密

    c++ - 我如何在类中创建一个返回值是该类对象类型的成员函数?

    generics - 通过特征而不是结构参数化变量?

    php - 从数据库中获取并分离单列数据

    PHP 字符串转 MySQL 日期

    php - 如何在本地主机和实时服务器上获得相同的 $_SERVER ['REQUEST_URI' ]

    php - 在对象被转换时返回特定值的对象上的函数

    JavaFX:公开 ObjectProperty 成员而不是 getter/setter?

    c# - 多态性和转换问题

    ruby-on-rails - 为什么 Rails 中带有 source_type 的多态关联会导致错误的 SQL 语句?