jke*_*esh 1 php subclass factory-pattern superclass
我正在编写一个带有子类的php应用程序,因为我想有多种方法来创建一个对象,我正在做不同的工厂方法而不是多个构造函数.
我有一个User工厂方法
User::from_id
User::from_netid
Run Code Online (Sandbox Code Playgroud)
我有几个子类User.我之前调用了父超级构造函数,但是当我切换到工厂方法时,构造函数不存在.
我有Student,一个子类User.为了使它工作,我不得不将几乎所有的超类工厂代码复制User::from_id到load_by_id,因为在这种情况下实例已经存在:
// In Student.php - Student extends User
public static function from_id_and_course($id, $course){
$instance = new self();
$instance->load_by_id($id);
$instance->course = $course;
...
}
Run Code Online (Sandbox Code Playgroud)
我想从子类中调用超类工厂方法作为起点,然后继续添加其他字段.像这样......
$instance = User::from_id($id);
Run Code Online (Sandbox Code Playgroud)
要么
$instance = Student::from_id($id);
Run Code Online (Sandbox Code Playgroud)
但在这些情况下,它给了我一个User对象,我需要一个Student对象.我能做到这一点的唯一方法就是这样做$instance = new self().
如何从子类中调用超类工厂方法作为创建新子类工厂方法的起点?
你的问题是这样的:
$instance = new self();
Run Code Online (Sandbox Code Playgroud)
self 是指定义方法的类,而不是调用者:
Student::from_id()被调用时,如果它不存在,它就会回落User::from_id().User::from_id(),self指User,不是Student.您必须使用后期静态绑定:
$instance = new static();
Run Code Online (Sandbox Code Playgroud)
然而,就像我一直这样,我强烈建议反对它.您最好使用对象范围而不是静态范围.它更容易扩展,虚假或模拟和偶然的测试.
没有错:
$user = new User;
$user->from_id($id);
$student = new Student;
$student->from_id($id);
Run Code Online (Sandbox Code Playgroud)
......它实际上更好.