Я знаю, что не возможно определить конструктора в интерфейсе. Но я задаюсь вопросом, почему, потому что я думаю, что это могло быть очень полезно.
Таким образом, Вы могли быть уверены, что некоторые поля в классе определяются для каждой реализации этого интерфейса.
Например, рассмотрите следующий класс сообщений:
public class MyMessage {
public MyMessage(String receiver) {
this.receiver = receiver;
}
private String receiver;
public void send() {
//some implementation for sending the mssage to the receiver
}
}
Если определение интерфейса для этого класса так, чтобы у меня могло быть больше классов, которые реализуют интерфейс сообщения, я могу только определить отправить метод а не конструктора. Таким образом, как я могу удостовериться, что каждой реализации этого класса действительно установили получатель? Если я использую метод как setReceiver(String receiver)
Я не могу быть уверен, что этот метод действительно называют. В конструкторе я мог гарантировать его.
Принимая некоторые из описанных вами вещей:
«Таким образом, вы можете быть уверены, что некоторые поля в классе определены для каждой реализации этого интерфейса».
«Если a определить a Интерфейс для этого класса, чтобы у меня было больше классов , реализующих интерфейс сообщений, я могу определить только метод отправки , а не конструктор "
... эти требования - это именно то, что абстрактные классы предназначены для.
Интерфейс определяет контракт для API, то есть набор методов, о которых договорились реализатор и пользователь API. У интерфейса нет инстансной реализации, следовательно, нет конструктора.
Описанный вами случай использования напоминает абстрактный класс, в котором конструктор вызывает метод абстрактного метода, который реализован в дочернем классе.
Неотъемлемая проблема здесь заключается в том, что пока выполняется базовый конструктор, дочерний объект еще не построен, и поэтому находится в непредсказуемом состоянии.
Подводя итог: не напрашивается ли проблема, когда вы вызываете перегруженные методы из родительских конструкторов, цитирую mindprod:
В общем случае вы должны избегать вызова любых не конечных методов в конструкторе. Проблема заключается в том, что экземпляр инициализаторы / инициализация переменных в производном классе выполняются после конструктора базового класса. класса.
Зависимости, которые не упоминаются в методах интерфейсов, следует рассматривать как детали реализации, а не как то, что заставляет интерфейс. Конечно, могут быть исключения, но, как правило, вы должны определить свой интерфейс в соответствии с ожидаемым поведением. Внутреннее состояние данной реализации не должно быть проблемой дизайна интерфейса.
См. этот вопрос для почему (взято из комментариев).
Если вам действительно нужно сделать что-то подобное, вам может понадобиться абстрактный базовый класс, а не интерфейс.