親クラスと子クラスがあるとします。親クラスはいくつかのパラメータをチェックし、指定されたリクエストを処理するには子クラスの方が適していると判断します - 既存の (親) オブジェクトを親オブジェクトから子クラスのオブジェクトとして再作成する方法はありますか?
親クラスの例:
/**
* 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
問題は、オブジェクトを作成するときに aまたはsuv
object が必要かどうかがわからないことです。$config
メソッドで解析されるまで、文字列に含まれるオプションはわかりません$car->configure()
(文字列は、ユーザー入力など、どこからでも取得できます)。
簡単な回避策は、オブジェクトを作成する前にconfigure
メソッドを移動しcar
て文字列を分析することです-ただし、論理的にはオブジェクトに属しているcar
ため、そこに保持したいと思います:)
このパズルを解く方法はありますか? そうでない場合、「最もクリーンな」回避策として何を提案しますか?
前もって感謝します!
編集:
指摘されたように、私の質問はこれと非常によく似ています:現在のオブジェクト ($this) を子孫クラスにキャストする 技術的には可能ですが、行うべきではないと答えています。ただし、説得力のある代替手段はまだ提案されていません (ファクトリを使用することが提案されていますが、これは問題の一部を解決するだけだと思います)。