假设我们有一个父类和一个子类。父类检查一些参数并确定子类更适合处理给定的请求 - 有没有办法从父对象中重新创建现有(父)对象作为子类的对象?
父类示例:
/**
* 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);
挑战在于我不知道在创建对象时是否需要car
或suv
对象;我不知道$config
字符串包含哪些选项,直到它在$car->configure()
方法中被解析(字符串可以来自任何地方,例如用户输入)。
一个简单的解决方法是在创建任何对象之前将configure
方法移出car
来分析字符串 - 但是,它在逻辑上属于car
对象,所以我会真的很想保留它:)
有没有办法解决这个难题?如果没有,你会建议什么是“最干净”的解决方法?
提前致谢!
修改
正如有人指出的那样,我的问题与此问题非常相似:Cast the current object ($this) to a descendent class 那里的答案说它在技术上是可行的,但是不应该这样做。然而,尚未提出令人信服的替代方案(有人建议使用工厂,但我觉得这只会解决部分问题)。
答案 0 :(得分:0)
正如评论中所说,做你想做的最常见的方法是使用静态方法将字符串作为参数并返回正确的实例。 这样,您可以将方法保留在汽车类中,正如您所说,这是最合乎逻辑的。
顺便说一句,如果更多的是在现有对象上添加功能。您可以考虑Decorator pattern。这样,您可以使用静态方法获取配置字符串和现有汽车,并返回给定的汽车装饰有与配置匹配的功能。这使您可以更灵活地利用所有优点和缺点(您可以在拖拉机上安装天窗)。