Метод вызова суперкласса в PHP из метода фабрики подклассов - PullRequest
1 голос
/ 21 декабря 2011

Я пишу php-приложение с подклассами, и, поскольку я хочу иметь несколько способов создания объекта, я использую различные фабричные методы вместо нескольких конструкторов.

У меня есть User с заводскими методами

User::from_id
User::from_netid

У меня есть несколько подклассов 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;
    ...
}

Я хочу вызвать метод фабрики суперкласса из подкласса в качестве отправной точки, а затем продолжить добавление других полей. Как то так ...

$instance = User::from_id($id);

или

$instance = Student::from_id($id);

но в этих случаях он дает мне User объект, и мне нужен Student объект. Единственный способ, которым я мог бы достичь этого, это сделать $instance = new self().

Как я могу вызвать метод фабрики суперкласса из подкласса в качестве отправной точки для создания нового метода фабрики подкласса?

Ответы [ 2 ]

5 голосов
/ 21 декабря 2011

Ваша проблема заключается в следующем:

$instance = new self();

self относится к классу, в котором определен метод, а не к вызывающему:

  • Когда вызывается Student::from_id(), если он не существует, он возвращается к User::from_id().
  • В User::from_id(), self относится к User, а не Student.

Вы должны использовать поздние статические привязки :

$instance = new static();

Однако, как и всегда, я настоятельно рекомендую против этого. Вам лучше использовать область объекта, чем статическую область. Проще растягивать, подделывать или издеваться и, между прочим, проверять.

В этом нет ничего плохого:

$user = new User;
$user->from_id($id);

$student = new Student;
$student->from_id($id);

... на самом деле лучше.

1 голос
/ 21 декабря 2011

Если вы используете PHP 5.3 или выше, вы можете использовать Поздние статические привязки , которые теперь доступны:

class User
{
  public static function from_id($id)
  {
    // factory
    $object = new static();

    // setup

    // return
    return $object;
  }
}

class Student extends User { }

$student = Student::from_id($id); // $student should be of class Student

Примечание - вам, вероятно, лучше настроитьцелый заводской класс для издевательств / испытаний / здравомыслия ...

...