Есть ли способ указать необязательный метод в интерфейсе (чтобы контракт указывал только число/тип аргументов)?
Пожалуйста, дайте, возможно, немного больше понимания и понимания проблемы, и укажите решение? См. Например, это обсуждение: Дополнительные методы в интерфейсе Java
В приложении я использую Listeners, связанные с Persistence (Doctrine). Поэтому я использую некоторые из этих методов:
prePersist()
preUpdate()
postPersist()
postUpdate()
и т.п.
Теперь, в то время как рефакторинг, поскольку слишком много объектов (объектов, которые нужно сохранить), я решил разделить части этих методов на отдельные классы.
Однако не всем им нужны все методы pre-... и post-.... Мне нужно убедиться, что им задано соответствующее количество и тип аргументов. Как вы это делаете в 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
}
}
См. Пример здесь:
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
}
}
Я нашел интересную библиотеку, представляющую WeakInterfaces. Однако я не думаю, что было бы легко заставить его работать с Доктриной.
После прочтения ваших комментариев и интернета, я решил выбрать еще один вариант для дизайна приложения.
Я создал единый интерфейс со всеми (необходимыми и готовыми) способами. Умножая количество интерфейсов для выполнения простой задачи (особенно в упомянутом случае), я считаю очень плохой подход. Это связано с тем, что я считаю, что идея класса и интерфейса заключается в том, чтобы объединить связанные вещи, а не разделить их "искусственно" на отдельные "контейнеры". (Подумайте, например, о POPO в PHP/POJO на Java).
Теперь всем классам необходимо реализовать все потенциальные методы, но некоторые из них могут быть пустыми или вызывать исключение, как указано в обсуждении со ссылкой, приведенной выше, или GolezTrol в его комментарии. Спасибо за интерес, во всяком случае.