При построении MVC-фреймворка на PHP я столкнулся с проблемой, которую можно было легко решить с помощью дженериков в стиле Java. Абстрактный класс Controller может выглядеть примерно так:
abstract class Controller {
abstract public function addModel(Model $model);
Может быть случай, когда подкласс класса Controller должен принимать только подкласс Model. Например, ExtendedController должен принимать ReOrderableModel только в методе addModel, потому что он предоставляет метод reOrder(), к которому ExtendedController должен иметь доступ:
class ExtendedController extends Controller {
public function addModel(ReOrderableModel $model) {
В PHP сигнатура унаследованного метода должна быть точно такой же, поэтому подсказка типа не может быть изменена на другой класс, даже если класс наследует тип класса, указанный в суперклассе. В java я бы просто сделал это:
abstract class Controller<T> {
abstract public addModel(T model);
class ExtendedController extends Controller<ReOrderableModel> {
public addModel(ReOrderableModel model) {
Но в PHP нет поддержки дженериков. Есть ли решение, которое по-прежнему придерживалось бы принципов ООП?
Править Я знаю, что PHP вообще не требует подсказки типа, но, возможно, это плохой ООП.Во-первых, из интерфейса (сигнатуры метода) не очевидно, какие объекты следует принимать. Поэтому, если другой разработчик хочет использовать метод, должно быть очевидно, что требуются объекты типа X без необходимости просматривать реализацию (тело метода), что является плохой инкапсуляцией и нарушает принцип сокрытия информации. Во-вторых, из-за отсутствия безопасности типов метод может принимать любую недопустимую переменную, а это означает, что ручная проверка типов и генерация исключений необходимы повсюду!