Есть ли способ указать необязательный метод в интерфейсе (чтобы в контракте указывалось только количество / тип аргументов, которые должны быть приведены)?
Пожалуйста, дайте, возможно, немного больше понимания и понимания проблемы, и укажите решение? Смотрите, например, это обсуждение: Необязательные методы в интерфейсе Java
В приложении я использую Слушатели, связанные с Постоянством (Doctrine). Поэтому я использую некоторые из этих методов:
prePersist()
preUpdate()
postPersist()
postUpdate()
и т.п.
Теперь, во время рефакторинга, поскольку существует слишком много сущностей (объектов, которые необходимо сохранить), я решил разделить части этих методов на отдельные классы.
Однако не всем из них нужны все методы до и после. Мне нужно убедиться, что им дано соответствующее количество и тип аргументов. Как вы это делаете в PHP?
Нет. Вся идея интерфейсов состоит в том, чтобы иметь контракт, который гарантирует, что метод существует.
Но класс может реализовывать несколько интерфейсов, поэтому вы можете определить другой интерфейс, содержащий этот метод, и не добавлять этот интерфейс в класс, у которого нет метода.
Интерфейсы не могут иметь дополнительных методов. Это концепция интерфейса. Однако, если вам нужно что-то необязательное, я предлагаю дополнительно создать реализацию вашего интерфейса по умолчанию, которая затем расширит все необходимые вам классы. Таким образом, все эти классы будут реализовывать интерфейс, и вы также сможете переопределять только выбранные методы, используя ваше необязательное поведение.
Что-то вроде того:
interface MyInterface {
public function method1();
public function method2();
}
Затем базовый класс реализует методы вашего интерфейса (я сделал его абстрактным, чтобы запретить прямое использование):
abstract class Base implements MyInterface {
public function method1() {
// dummy
}
public function method2() {
// dummy
}
}
а потом:
class Optional extends Base {
// method1 is not overridden, so Base' implementation applies
public function method2() {
// something here
}
}
Я нашел интересную библиотеку, представляющую WeakInterfaces. Однако я не думаю, что было бы легко заставить это работать с Доктриной.
Пожалуйста, посмотрите пример здесь:
interface Workable
{
public function work();
}
interface Feedable
{
public function eat();
}
interface Employee extends Feedable, Workable
{
}
class Human implements Employee
{
public function work()
{
// ....working
}
public function eat()
{
//.... eating in lunch break
}
}
// robot can only work
class Robot implements Workable
{
public function work()
{
// ....working
}
}
Прочитав ваши комментарии, а также интернет, я решил выбрать другой обходной путь для дизайна приложения.
Я создал единый интерфейс со всеми (обязательными и необязательными) методами. Умножение количества интерфейсов для достижения простой задачи (особенно в упомянутом случае) я считаю действительно плохим подходом. Это потому что Я полагаю, что идея класса и интерфейса состоит в том, чтобы соединять вещи вместе, а не разбивать их «искусственно» на отдельные «контейнеры». (Подумайте, например, о POPO в PHP / POJO в Java).
Теперь все классы должны реализовывать все потенциальные методы, но некоторые из них могут быть пустыми или выдавать исключение, как указано в обсуждении со ссылкой, приведенной выше, или с помощью GolezTrol в своем комментарии. В любом случае, спасибо за интерес.