1

考虑以下代码:

class Vehicle {

    /**
    * Create a new instance of Vehicle
    * 
    * @return Vehicle
    */
    public static function create(){

        return eval( "return new " . get_called_class() . '();' );
        // return self(); would always return Vehicle reg ardless

    }


    public function drive(){

        echo "I am a Vehicle!";

    }

}

class Bus extends Vehicle {

    public function drive(){

        parent::drive();

        echo "\nSpecifically, a bus!";

    }

}


class Car extends Vehicle {

    public function drive(){

        parent::drive();

        echo "\nSpecifically, a car!";

    }

}

// Drive a car
    Car::create()->drive();

// Drive a bus
    Bus::create()->drive();

我在 Vehicle 类中实现了一个工厂“create”方法,它允许我获取我想要使用的类的实例。

我尝试使用“return new self();” 但这总是返回一个 Vehicle 的实例,所以我求助于使用 eval。

问题:是否有一种非评估方式来实现 create() 方法,以便:

  • 它返回您正在使用的类的实例
  • 它不需要在每个扩展类上实现 create()
4

3 回答 3

4

使用静态而不是self,例如

<?php
class Vehicle {
    public static function create(){
        return new static();
    }

    public function drive(){
        echo "I am a Vehicle!";
    }
}

class Bus extends Vehicle {
    public function drive(){
        parent::drive();
        echo "\nSpecifically, a bus!";

    }
}

$b = Bus::create();
$b->drive();

印刷

I am a Vehicle!
Specifically, a bus!
于 2012-10-19T21:21:06.573 回答
1

(VolkerK 击败了我,但这有轻微的变化)

等等,你为什么需要eval()呢?不会:

public static function create() {
    $class = get_called_class();

    return new $class();
}

工作?

于 2012-10-19T21:22:58.627 回答
0

最好的方法是将工厂方法从具体类型中移到它自己的工厂类中。然后,您不仅可以更轻松地处理此问题,还可以轻松地将工厂替换为另一个工厂。

我假设您知道对象继承是如何工作的,因此您不必处理任何不那么直截了当并且很快就开始以某种方式站立的静态事物。

于 2012-10-20T00:12:32.967 回答