如何根据对象的真实类名运行代码


How do I run code based on the true class name of an object?

我正在浏览一个对象列表,所有对象都具有相同的父类,但它们可能是来自许多子类之一的实例。 根据对象的真实类型,我想执行略有不同的操作。

如何根据对象类型运行不同的代码块?

在Java中,我会用我想使用的每种类型重载处理函数,但PHP不允许这样做。

背景:对于戈登的评论。

我们正在从一组对象构建表单。扩展为表示特定类型的表单元素的超类组件。 TextInput extends Component和组件能够容纳其他组件。 我们不希望他们对自己的实际代表负责。

我们现在正在努力构建 HTML,但我们可能希望使用它们来构建 .PDF 或其他格式。

因此,我们有代码通过组件,并递归地通过它包含的组件。 根据组件的类型,我们需要创建不同的输出。

使用

if($myobject instanceof class1){
}elseif($myobject instanceof class1){
}

switch(get_class($myobject)){
    case 'class1':
       break;
    case 'class2':
       break;
}

另外,确保你不要打破开放/关闭原则。如果将该部分代码放在类中而不是控制器的特定部分中,则最终会破坏代码的重要可重用性功能:

开/闭原理

你从来没有做过插件系统吗?如果你这样做了,我相信你没有 要求用户在代码中对加载行进行硬编码以处理该行 插件吧?

正常来说,您希望您的课程可以在没有 需要更改父级。扩展应该是一个开放的原则 添加更多代码应该像扩展一样简单,但你应该 永远不必修改父类。

因此,在父类内部或另一个类内添加一个开关来处理 该类的所有可能版本都打破了开放原则,因为用户 然后必须更改类以添加更多功能...

    创建一个抽象类,
  1. 该类表示对象的所有常见功能,并指示它们必须具有的其他方法,以便您可以确保每次都使用相同的接口(这些方法称为抽象方法)。

  2. 然后为每个特定类型的对象创建子类。它们必须实现主抽象类中的所有抽象方法。

  3. 然后使用工厂模式根据确定对象类型的任何标志(也称为子类)动态创建适当的对象。

像这样尝试 smth

function objectProcessor_A($o) {}
function objectProcessor_B($o) {}
function objectProcessor_C($o) {}
foreach($objects AS $o) {
    if(function_exist("objectProcessor_" . get_class($o)))
        call_user_func("objectProcessor_" . get_class($o), $o);
}

现在,我认为,最好的解决方案是使用继承。无法更改$o的行为/库代码?比使用工厂和添加方法作为匿名函数:

class OFactory {
    static function getO($type) {
        $r = new $type();
        if($type === "A") {
            $r.processor = function() {...};
        } else if($type === "B") {
            $r.processor = function() {...};
        } else if($type === "C") {
            $r.processor = function() {...};
        }
        return $r;
    }
}
$a = OFactory::getO("A");
call_user_func($a->processor);
$b = OFactory::getO("B");
call_user_func($b->processor);