Как замаскировать дочерние классы в родительском классе с помощью автозагрузки (php)

У меня есть базовый класс, который наследуется примерно десятью подклассами. Большинство этих подклассов имеют очень похожее поведение, но я хочу определить специализированные методы только для трех из них.

Можно ли замаскировать существование этих классов, автоматически загружая родительский класс каждый раз, когда создается экземпляр объекта дочернего класса? Таким образом, мне не пришлось бы определять несколько классов с одним и тем же кодом?

E.g.

class ParentClass {
    public function __construct() {
        switch(get_class($this)) {
            case "ChildClass1" : do_stuff() break;
            case "ChildClass2" : do_other_stuff() break;
            default: break;
        }
    }
}

$c1 = new ChildClass1();
$c2 = new ChildClass2();

...и иметь только один файл ParentClass.php (без отдельных файлов ChildClass1.php или ChildClass2.php).


person Cat    schedule 20.09.2010    source источник
comment
Не искажайте свой код, чтобы не создавать пару файлов. Если вы поместите общую реализацию в ParentClass и переопределите только там, где это необходимо, в дочерних классах, файлы ChildClass1.php и ChildClass2.php не будут иметь дублированный код.   -  person grossvogel    schedule 21.09.2010


Ответы (3)


Почему бы тебе просто не сделать это?

class ParentClass {
  public function __construct()
  {
    $this->do_stuff();
  }
}

class SpecializedClass
  extends ParentClass
{
  public function __construct()
  {
    // Optional, do the stuff parent does (do_stuff());
    parent::__construct();
    // ... specialized construction logic here
    $this->do_other_stuff();
  }

  // ... specialized methods here.
}

class NormalClass1
  extends ParentClass
{

}

class SpecialClass1
  extends SpecializedClass
{

}

// ... etc.
person Sam Day    schedule 20.09.2010
comment
Как моя среда находит эти классы? Моя текущая настройка автоматически загружает класс, если он находится в отдельном файле, но не может загрузить класс, если он определен в другом файле класса. - person Cat; 21.09.2010
comment
Ах, я понимаю, что вы спрашиваете здесь. На мой взгляд, полагаться на функциональность __autoload — отличный способ очень быстро получить запутанную кодовую базу. Вы должны сгруппировать связанные классы в файлы и запрашивать их при необходимости вручную. Использование require_once прекрасно, потому что если у вас циклические зависимости или сложная цепочка зависимостей, вы не собираетесь включать один и тот же набор классов более одного раза. - person Sam Day; 21.09.2010

Вам нужно будет добавить логику в функцию __autoload() или spl_autoload_register(), которая путем сравнения строк решает, какой файл загрузить / если он, возможно, является одним из дочерних элементов вашего родителя.

person Wrikken    schedule 20.09.2010

На мой взгляд, полезно поддерживать соглашение об одном классе в файле. Это делает автозагрузчик простым, облегчает повторное использование отдельных классов и, что наиболее важно, упрощает навигацию и анализ исходного кода. Если у вас много классов с общим родителем, подумайте о том, чтобы переместить их в отдельный подкаталог и добавить этот каталог в автозагрузчик.

Это не обязательно верно для языков, отличных от PHP, которые имеют лучшую семантику импорта.

person Adam Byrtek    schedule 20.09.2010