Когда я в первой части говорил что интерфейсы, для начального понимания, можно сперва представлять как полностью абстрактные классы, я говорил это именно для начального понимания. Значение и применение интерфейсов выходит далеко за пределы этого начального понимания.
Лучше представлять интерфейсы как некие контракты, договора, которые определяют правила (интерфейс) взаимодействия между компонентами программы и при этом не указывают каким образом этот договор может быть реализован, главное чтобы он вписывался в рамки определения методов в интерфейсе. Реализаций же одного договора может быть сколько угодно много. Реализовывают договора описанные в интерфейсах классы, и они должны строго соблюдать договор описанный в интерфейсе, то есть реализовать все методы имплементируемых интерфейсов.
По идее интерфейсы, как и следует из их названия, предоставляют API тем классам которые их имплементируют.
Интерфейсы это еще больший уровень абстракции чем абстрактные классы :)
В действительности, сперва возникает много вопросов по поводу интерфейсов – зачем они вообще нужны, если там нет реализации методов а только их определения? Но как ни странно интерфейсы – это мощнейшая вещь для реализации инкапсуляции, полиморфизма и наследования, которая сильно расширяет возможности классов.
Ну ладно, от слов к делу. Попрактикуемся на хорошем примере видео, которое я уже предлагал для вашего просмотра.
Давайте реализуем этот урок на практике! Правда, я конечно немного изменю код представленный в этом уроке, но в основном все останется так же как там. Полностью рабочий код можно посмотреть тут.
Во второй мутации данного проекта я добавил интерфейс IReplacer и его имплементацию в классе DefaultReplacer.
Код интерфеса IReplacer:
package
pro.java.smile2;public interface IReplacer {
String replace(IReader reader, String from, String to);
}
Код класса DefaultReplacer:
package
pro.java.smile2;public
class DefaultReplacer implements IReplacer {@Override
public String replace(IReader reader, String from, String to) {
return reader.read().replace(from, to);
}
}
Как видно метод объявленный в IRepalcer использует в качестве входного аргумента объект типа IReader, через который получает строку для замены, а так же подстроки для замены – с какой (from) на какую (to).
Надеюсь на этих примерах стало чуть более понятно как и для чего могут использоваться интерфейсы, а так же вся мощь и гибкость которую они предоставляют.
Хотя можно еще один пример привести – это реализация целочисленного стека. Идея взята из книги Герберта Шилдта, но в ней, этот пример, показался мне несколько странным, так как он не отражает идеи использования интерфейсов, поскольку там создается объект самого стека, а не интерфейсная ссылка на него. То есть в его примере можно легко было бы обойтись простыми классами.
Кроме того я добавил в этот пример метод печати стека, дабы было видно что происходит.
Комментариев нет:
Отправить комментарий