Чтение онлайн

на главную - закладки

Жанры

Философия Java3

Эккель Брюс

Шрифт:

Класс Filter содержит те же интерфейсные элементы, что и Processor, но, поскольку он не является производным от Processor (создатель класса Filter и не подозревал, что вы захотите использовать его как Processor), он не может использоваться с методом Apply.process, хотя это выглядело бы вполне естественно. Логическая привязка между Apply.process и Processor оказывается более сильной, чем реально необходимо, и это обстоятельство препятствует повторному использованию кода Apply.process. Также обратите внимание, что входные и выходные данные

относятся к типу Waveform.

Но, если преобразовать класс Processor в интерфейс, ограничения ослабляются и появляется возможность повторного использования Apply.process. Обновленные версии Processor и Apply выглядят так:

//: interfaces/interfaceprocessor/Processor.java package interfaces interfaceprocessor;

public interface Processor { String nameO;

Object process(Object input), } ///-

//. interfaces/interfaceprocessor/Apply.java package i nterfaces.i nterfaceprocessor, import static net mindview.util.Print.*:

public class Apply {

public static void process(Processor p. Object s) { print ("Using Processor " + p.nameO): print(p.process(s)):

}

} ///:-

В первом варианте повторного использования кода клиентские программисты пишут свои классы с поддержкой интерфейса:

//: interfaces/interfaceprocessor/StringProcessor.java package i nterfaces.i nterfaceprocessor; import java.util.*;

public abstract class StringProcessor implements Processor! public String nameO {

return getClassO getSimpleNameO;

}

public abstract String process(Object input); public static String s =

"If she weighs the same as a duck, she's made of wood"; public static void main(String[] args) { Apply, process (new UpcaseO, s); Apply, process (new DowncaseO, s); Apply, process (new SplitterO. s);

class Upcase extends StringProcessor {

public String process(Object input) { II Ковариантный возвращаемый тип return ((String)input) .toUpperCaseO;

class Downcase extends StringProcessor { public String process(Object input) {

return ((String)input).toLowerCase;

class Splitter extends StringProcessor {

public String process(Object input) {

return Arrays.toString(((String)input).split(" ")).

}

} /* Output

Используем Processor Upcase

IF SHE WEIGHS THE SAME AS A DUCK, SHE'S MADE OF WOOD Используем Processor Downcase if she weighs the same as a duck, she's made of wood Используем Processor Splitter

[If. she. weighs, the. same. as. a. duck., she's, made. of. wood] *///:-

Впрочем, довольно часто модификация тех классов, которые вы собираетесь использовать, невозможна. Например, в примере с электронными фильтрами библиотека была получена из внешнего источника. В таких ситуациях применяется паттерн «адаптер»: вы пишете код, который получает имеющийся интерфейс, и создаете тот интерфейс, который вам нужен:

//: interfaces/interfaceprocessor/FilterProcessor java package interfaces interfaceprocessor, import interfaces.filters.*;

class FilterAdapter implements Processor { Filter filter.

public FilterAdapter(Filter filter) { this.filter = filter.

}

public String nameO { return filter.nameO; } public Waveform process(Object input) {

return filter.process((Waveform)input).

}

}

public class FilterProcessor {

public static void main(String[] args) { Waveform w = new Waveform; -

Apply process(new FilterAdapter(new LowPass(l.O)), w); Apply.process(new FilterAdapter(new HighPass(2.0)). w); Apply.process(

new FilterAdapter(new BandPass(3.0. 4 0)). w);

}

} /* Output.

Используем Processor LowPass Waveform 0

Используем Processor HighPass Waveform 0

Используем Processor BandPass

Waveform 0 *///.-

Конструктор FilterAdapter

получает исходный интерфейс (Filter) и создает объект с требуемым интерфейсом Processor. Также обратите внимание на применение делегирования в классе FilterAdapter.

Отделение интерфейса от реализации позволяет применять интерфейс к разным реализациям, а следовательно, расширяет возможности повторного использования кода.

«Множественное наследование» в Java

Так как интерфейс по определению не имеет реализации (то есть не обладает памятью для хранения данных), нет ничего, что могло бы помешать совмещению нескольких интерфейсов. Это очень полезная возможность, так как в некоторых ситуациях требуется выразить утверждение: «Икс является и А, и Б, и В одновременно». В С++ подобное совмещение интерфейсов нескольких классов называется множественным наследованием, и оно имеет ряд очень неприятных аспектов, поскольку каждый класс может иметь свою реализацию. В Java можно добиться аналогичного эффекта, но, поскольку реализацией обладает всего один класс, проблемы, возникающие при совмещении нескольких интерфейсов в С++, в Java принципиально невозможны:

При наследовании базовый класс вовсе не обязан быть абстрактным или «реальным» (без абстрактных методов). Если наследование действительно осуществляется не от интерфейса, то среди прямых «предков» класс может быть только один — все остальные должны быть интерфейсами. Имена интерфейсов перечисляются вслед за ключевым словом implements и разделяются запятыми. Интерфейсов может быть сколько угодно, причем к ним можно проводить восходящее преобразование. Следующий пример показывает, как создать новый класс на основе реального класса и нескольких интерфейсов:

Поделиться:
Популярные книги

Пушкарь. Пенталогия

Корчевский Юрий Григорьевич
Фантастика:
альтернативная история
8.11
рейтинг книги
Пушкарь. Пенталогия

Тихие ночи

Владимиров Денис
2. Глэрд
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Тихие ночи

Отверженный VI: Эльфийский Петербург

Опсокополос Алексис
6. Отверженный
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Отверженный VI: Эльфийский Петербург

Второгодка. Книга 2. Око за око

Ромов Дмитрий
2. Второгодка
Фантастика:
героическая фантастика
альтернативная история
фэнтези
5.00
рейтинг книги
Второгодка. Книга 2. Око за око

Ваше Сиятельство 7

Моури Эрли
7. Ваше Сиятельство
Фантастика:
боевая фантастика
аниме
5.00
рейтинг книги
Ваше Сиятельство 7

Бастард Императора. Том 9

Орлов Андрей Юрьевич
9. Бастард Императора
Фантастика:
городское фэнтези
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Бастард Императора. Том 9

Черта прикрытия

Бэнкс Иэн М.
9. Культура
Фантастика:
боевая фантастика
космическая фантастика
киберпанк
6.67
рейтинг книги
Черта прикрытия

Изгой Проклятого Клана

Пламенев Владимир
1. Изгой
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Изгой Проклятого Клана

Дважды одаренный. Том III

Тарс Элиан
3. Дважды одаренный
Фантастика:
альтернативная история
аниме
фэнтези
фантастика: прочее
юмористическое фэнтези
5.00
рейтинг книги
Дважды одаренный. Том III

Источники силы

Amazerak
4. Иной в голове
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Источники силы

Эммануэль

Арсан Эммануэль
1. Эммануэль
Любовные романы:
эро литература
7.38
рейтинг книги
Эммануэль

Распутье

Басаргин Иван Ульянович
Сибириада
Проза:
военная проза
историческая проза
5.00
рейтинг книги
Распутье

Бродяга 3

Первухин Андрей Евгеньевич
3. Бродяга
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Бродяга 3

Трое с площади Карронад

Крапивин Владислав Петрович
Детские:
детские приключения
9.10
рейтинг книги
Трое с площади Карронад