@topuserman

Интерфейс при наследовании метода: как правильно сделать?

interface IUser {
    public static function getById(): IUser;
}
interface IAdmin extends IUser { ... }

class User implements IUser {
      public static function getById(): IUser {  ... }
}

class Admin extends User  implements IAdmin {
   // ...
}


Есть базовый класс User, от которого наследуются другие классы, например Admin.
Метод getById реализован только у базового класса, а нужна возможность, чтобы наследники, также могли воспользоваться этим методов, т.к. наследники - это теже пользователи, лишь с некоторыми дополнениями.

Метод get должен возвращать свой же объект, и при реализации возникает проблема:
когда класс User возвращает new self, то все работает хорошо, т.к. ожидаемый тип данных - IUser, а класс User как раз его и реализует.

Но если наследники будут делать return self, например класс Admin, то результат будет типа IAdmin, а метод get ожидает тип IUser.

Проблема возникает из-за ковариантности и контравариантности.
Подскажите пожалуйста, какими способами можно решить мою проблему, и какой предпочтительнее ?

Использую php 7.3. Знаю что в php 7.4 реализован возвращаемый тип self.
т.е. можно сделать так: public static function getById(): self;

Мне нужно, чтобы каждый наследник, который использует метод getById возвращал self, но при этом ожидаемый тип для метода был допустимый.

UPD

также у меня скорее всего ошибки. должно быть не return self, а return static? но это все равно не решает проблему.
  • Вопрос задан
  • 129 просмотров
Пригласить эксперта
Ответы на вопрос 2
Adamos
@Adamos
Есть базовый класс User, от которого наследуются другие классы, например Admin.

Зря. Админ - это не разновидность пользователя, это вполне определенная роль на сайте, связанная с конкретным пользователем. Наследование здесь не имеет смысла, логика администрирования сайта и пользователя сайта не пересекаются.
Ответ написан
glaphire
@glaphire Куратор тега PHP
PHP developer
Тут есть обсуждение
https://stackoverflow.com/questions/39068983/php-7...
Может стоит отказаться от статики и возвращать IUser ?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы