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
класс (или суперкласс, если различные классы будут кодируемыми / декодируемыми).
Это не единичное правило. Существуют механизмы для достижения того, что вы хотите, не нарушая концепцию интерфейса. Подумайте об этом: что хорошего в этом методе для интерфейса, если вы можете получить к нему доступ только внутри пакета? Какой смысл иметь такие методы в интерфейсе, если они могут быть методами класса, которые также доступны членам пакета с соответствующими модификаторами?