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

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

Жанры

Философия Java3

Эккель Брюс

Шрифт:

print(this + ".playO " + n),

}

public String toStringO { return "Percussion"; } public void adjustO { print(this + " adjustO"); }

}

class Stringed implements Instrument { public void play(Note n) {

print(this + ".playO " + n);

}

public String toStringO { return "Stringed"; } public void adjustO { print(this + ".adjustO"); }

}

class Brass extends Wind {

public String toStringO { return "Brass"; }

}

class Woodwind extends Wind {

public String toStringO { return "Woodwind"; }

}

public class Music5 {

// Работа метода не зависит от фактического типа объекта. // поэтому типы, добавленные в систему, будут работать правильно: static void tune(Instrument i) { // .

i.play(Note.MIDDLE_C);

}

static void tuneAll(Instruments e) { for(Instrument i : e) tune(i);

}

public static void main(String[] args) {

// Восходящее преобразование при добавлении в массив. Instrument!!] orchestra = { new WindO. new PercussionO. new StringedO, new BrassO. new WoodwindО

}.

tuneAll(orchestra),

}

} /* Output: Wind.pi ayО MIDDLE_C Percussion.playO MIDDLE_C Stringed.pi ayО MIDDLE_C Brass.pi ayО MIDDLE_C Woodwind pi ayО MIDDLE_C */// ~

В этой версии присутствует еще одно изменение: метод what был заменен на toString. Так как метод toString входит в корневой класс Object, его присутствие в интерфейсе не обязательно.

Остальной код работает так же, как прежде. Неважно, проводите ли вы преобразование к «обычному» классу с именем Instrument, к абстрактному классу с именем Instrument или к интерфейсу с именем Instrument — действие будет одинаковым. В методе tune ничто не указывает на то, является класс Instrument «обычным» или абстрактным, или это вообще не класс, а интерфейс.

Отделение интерфейса от реализации

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

Представьте, что у нас имеется класс Processor с методами name и process. Последний получает входные данные, изменяет их и выдает результат. Базовый класс расширяется для создания разных специализированных типов Processor. В следующем примере производные типы изменяют объекты String (обратите внимание: ковариантными могут быть возвращаемые значения, но не типы аргументов):

//• interfaces/classprocessor/Apply.java package interfaces classprocessor; import java.util.*;

import static net.mindview.util.Print.*;

class Processor {

public String nameО {

return getClass.getSimpleName;

}

Object process(Object input) { return input; }

class Upcase extends Processor {

String process(Object input) { // Ковариантный возвращаемый тип return ((String)input) toUpperCase,

class Downcase extends Processor { String process(Object input) {

return ((String)input) toLowerCase,

class Splitter extends Processor { String process(Object input) {

// Аргумент splitO используется для разбиения строки return Arrays toString(((String)input) splitC ")),

public class Apply {

public static void process(Processor p. Object s) { print ("Используем Processor " + p nameO), print(p.process(s));

}

public static String s =

"Disagreement with beliefs is by definition incorrect"; public static void main(String[] args) { process(new UpcaseO, s); process(new Downcase, s); process(new SplitterO, s),

}

} /* Output:

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

DISAGREEMENT WITH BELIEFS IS BY DEFINITION INCORRECT Используем Processor Downcase disagreement with beliefs is by definition incorrect Используем Processor Splitter

[Disagreement, with, beliefs, is, by, definition, incorrect] *///-

Метод Apply.process получает любую разновидность Processor, применяет ее к Object, а затем выводит результат. Метод split является частью класса String. Он получает объект String, разбивает его на несколько фрагментов по ограничителям, определяемым переданным аргументом, и возвращает String[]. Здесь он используется как более компактный способ создания массива String.

Теперь предположим, что вы обнаружили некое семейство электронных фильтров, которые тоже было бы уместно использовать с методом Apply. process:

// interfaces/filters/Waveform java package interfaces.filters.

public class Waveform {

private static long counter;

private final long id = counter++; public String toStringO { return "Waveform " + id. } } Hill- interfaces/filters/Filter java package interfaces filters,

public class Filter {

public String nameO {

return getClassO getSimpleName.

}

public Waveform process(Waveform input) { return input; } } III ~

// interfaces/filters/LowPass java package interfaces filters,

public class LowPass extends Filter { double cutoff;

public LowPass(double cutoff) { this.cutoff = cutoff; } public Waveform process(Waveform input) {

return input; II Фиктивная обработка

}

} Hill i nterfaces/fi 1ters/Hi ghPass.java package interfaces.filters;

public class HighPass extends Filter { double cutoff;

public HighPass(double cutoff) { this.cutoff = cutoff; } public Waveform process(Waveform input) { return input. } } ///.-

// interfaces/filters/BandPass java package interfaces filters;

public class BandPass extends Filter { double lowCutoff. highCutoff; public BandPass(double lowCut. double highCut) { lowCutoff = lowCut; highCutoff = highCut;

}

public Waveform process(Waveform input) { return input; } } III-

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

Дворянин

Злотников Роман Валерьевич
2. Император и трубочист
Фантастика:
боевая фантастика
альтернативная история
5.00
рейтинг книги
Дворянин

Учитель из прошлого тысячелетия

Еслер Андрей
6. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Учитель из прошлого тысячелетия

Тринадцатый II

NikL
2. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый II

Дитя прибоя

Трофимов Ерофей
Дитя прибоя
Фантастика:
боевая фантастика
попаданцы
фэнтези
5.00
рейтинг книги
Дитя прибоя

Император Пограничья 9

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

Газлайтер. Том 1

Володин Григорий
1. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 1

Вперед в прошлое 2

Ратманов Денис
2. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 2

Кодекс Императора III

Сапфир Олег
3. Кодекс Императора
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Императора III

Родословная. Том 2

Ткачев Андрей Юрьевич
2. Линия крови
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Родословная. Том 2

Моров. Том 7

Кощеев Владимир
6. Моров
Фантастика:
альтернативная история
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Моров. Том 7

Имперец. Том 5

Романов Михаил Яковлевич
4. Имперец
Фантастика:
попаданцы
альтернативная история
аниме
6.00
рейтинг книги
Имперец. Том 5

Кукловод

Злобин Михаил
2. О чем молчат могилы
Фантастика:
боевая фантастика
8.50
рейтинг книги
Кукловод

Кодекс Охотника. Книга VI

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI

#Бояръ-Аниме. Газлайтер. Том 11

Володин Григорий Григорьевич
11. История Телепата
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 11