Java: защищенный метод в интерфейсе

Хорошо, я знаю, что этот вопрос задавался несколько раз, но мне нужен совет по моему конкретному случаю. Существуют кодируемые и декодируемые, и сообщение является и кодируемым, и декодируемым:

interface Encodable { void encode(); }
interface Decodable { void decode(); }
class Message implements Encodable, Decodable { ... }

void processEncodable(Encodable encodable) {
  ...
  encodable.encode();
  ...
}

Помимо Message есть и другие Encodable (и Decodable), которые необходимо обработать в processEncodable. Пока все хорошо, но проблема в том, что я хочу скрыть encode() и decode() снаружи пакета, а интерфейс Java не допускает использование защищенных / закрытых методов. Можно предложить абстрактные классы, но, как вы можете видеть, Message должен наследовать как Encodable, так и Decodable, так что это не так. Какие-либо предложения?

В эти дни я очень увлекаюсь Scala, и черты Scala допускают защищенные / приватные методы, и это более интуитивно понятно ИМХО. Я прошел через несколько ответов, в которых упоминалась философия дизайна Java-интерфейса, но я не совсем понимаю, почему он не должен разрешать защищенные методы, если интерфейс был введен как альтернатива множественному наследованию, в то время как абстрактные классы делают это..

1 ответ

Быть альтернативой не означает, что это полная замена. Интерфейсы - это контракты на обслуживание, и поэтому они предоставляют функциональные возможности, которые определенный класс предоставляет своим клиентам, будучи клиентом, имеющим доступ к интерфейсу.

Если хочешь спрятаться encode а также decode извне пакета (это означает, что ваша логика также должна оставаться в пакете с Message класс) не выставляйте их через интерфейс и, вместо этого, позволяйте им быть protected (или пакет приватных) методов вашего Message класс (или суперкласс, если различные классы будут кодируемыми / декодируемыми).

Это не единичное правило. Существуют механизмы для достижения того, что вы хотите, не нарушая концепцию интерфейса. Подумайте об этом: что хорошего в этом методе для интерфейса, если вы можете получить к нему доступ только внутри пакета? Какой смысл иметь такие методы в интерфейсе, если они могут быть методами класса, которые также доступны членам пакета с соответствующими модификаторами?

Другие вопросы по тегам