有什么方法可以让它发挥作用吗?见例:
class car {
function __construct($type){
switch ($type) {
case 'big' : return new big_car();
case 'small' : return new small_car();
}
}
function whatisit () {
echo "this is car ;( \n";
}
}
class big_car extends car {
function __construct(){}
function whatisit () {
echo "this is big car ;) \n";
}
}
class small_car extends car {
function __construct(){}
function whatisit () {
echo "this is small car ;) \n";
}
}
所以目标是以这种方式使用它:
$mycar = new car('big');
$mycar->whatisit(); // i want it to say that it's big
我非常认为它的方法不好而且它不能以这种方式工作,但也许有一个技巧?
PS ::我知道我可以使用特殊的静态方法,但......
答案 0 :(得分:9)
你需要一家汽车厂来制造新车;这不是JavaScript:)
class car_factory
{
function create_car($type = null)
{
switch ($type) {
case 'big':
return new big_car();
case 'small':
return new small_car();
case null:
return new car();
}
throw new InvalidArgumentException($type);
}
}
$factory = new car_factory;
$small_car = $factory->create_car('small');
$std_car = $factory->create_car();
当然,您应该从原始代码中删除__construct
功能。
作为注释中的mentioned,你可以通过使用动态类来完全概括它,假设类扩展具有相同的构造函数并且类命名是一致的:
class car_factory
{
function create_car($type = null)
{
if (is_null($type)) {
return new car();
}
$class = "{$type}_car";
if (class_exists($class)) {
$obj = new $class();
if ($obj instanceof car) {
return $obj;
}
}
throw new InvalidArgumentException($type);
}
}
我个人没有任何偏好;如果可扩展性是一个关键因素,那就去做吧,否则坚持使用简单的switch
。
答案 1 :(得分:1)
[...]你可以通过使用动态类来完全概括这一点,假设类扩展具有相同的构造函数并且类命名是一致的
您可以使用Reflection添加更多灵活性:
class car_factory
{
function create_car($class = null, $constructorArgs = array())
{
if (is_null($class)) {
return new car();
}
try {
$refl = new ReflectionClass($class);
if (!$refl->isSubclassOf('car') {
throw new DomainException("Type: {$class} is not a car type");
}
return $refl->newIntanceArgs($constructorArgs);
} catch(ReflectionException $e) {
throw new DomainException("Invalid car type: {$class}");
}
}
}
现在使用:
$factory = new car_factory();
$car1 = $factory->create_car('big_car');
$car2 = $factory->create_car('small_car');
$car3 = $factory->create_car('fancy_car_name_with_constructor_args', array("I'm fancy!"));