1

假设我们有一个父类和一个子类。父类检查一些参数并决定子类更适合处理给定的请求 - 有没有办法从父对象中重新创建现有(父)对象作为子类的对象?

父类示例:

/**
 * Simple car
 */
class car {
    /**
     * The constructor
     */
    public function __construct() {
        // (...)
    }

    /**
     * Add a sunroof to the car
     */
    protected function addSunRoof() {
        // (...)
    }

    /**
     * Parse a config string and configure the car accordingly
     * @param string $config
     */
    public function configure($config) {
        $options = explode(";", $config);

        // Do something for every option in $config string
        foreach ($options as $o) {
            switch ($o) {
                case "sunroof" : 
                    $this->addSunRoof();
                    break;
                case "4x4" :
                    // 'car' does not have support for '4x4', but the child class 'suv' does
                    // -> This 'car' object should therefore 'evolve' and become a 'suv' object - how?
                case "foo" :
                // (...)
            } // switch

        } // foreach
    } // configure
} // car

子类示例:

/**
 * SUV car
 */
class suv extends car {
    /**
     * Add 4x4 drive
     */
    protected function add4x4() {
        // (...)
    } // add4x4
} // suv

现在,获取suv对象最明显的方法是直接从头开始创建它:

$car = new suv();
$car->configure($config);

挑战在于我不知道创建对象时是否需要acarsuv对象;我不知道$config字符串包含哪些选项,直到它在$car->configure()方法中被解析(字符串可以来自任何地方,例如用户输入)。

一个简单的解决方法是在创建任何对象之前将该configure方法移出car分析字符串 - 但是,它在逻辑上属于该car对象,所以我真的很想把它保留在那里:)

有没有办法解决这个难题?如果没有,您会建议什么作为“最干净”的解决方法?

提前致谢!

编辑:

正如有人指出的那样,我的问题与这个问题非常相似:将当前对象 ($this) 转换为后代类 那里的答案说这在技术上是可行的,但不应该这样做。但是,尚未提出令人信服的替代方案(有人建议使用工厂,但我觉得这只能解决部分问题)。

4

1 回答 1

0

正如评论中所说,做你想做的最常见的方法是使用一个静态方法,将字符串作为参数并返回正确的实例。这样,您可以将方法保留在 car 类中,正如您所说,这是最合乎逻辑的。

顺便说一句,如果更多的是在现有对象上添加功能。您可能会考虑装饰器模式。这样,您可以使用静态方法获取配置字符串和现有汽车,并返回装饰有与配置匹配的功能的给定汽车。这使您可以更灵活地处理所有优点和缺点(您可以在拖拉机上安装天窗)。

于 2013-06-26T23:00:25.677 回答