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

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

Жанры

Философия Java3

Эккель Брюс

Шрифт:

//: polymorphi sm/RTTI java

// Нисходящее преобразование и динамическое определение типов (RTTI)

// {ThrowException}

class Useful {

public void f {} public void g {}

}

class MoreUseful extends Useful { public void f {} public void g {} public void u {} public void v {} public void w {}

}

public class RTTI {

public static void main(String[] args) { Useful[] x = {

new Useful О. new MoreUsefulО

}:

x[0].f: x[l] g.

// СТадия компиляции- метод не найден в классе Useful• //! x[l].u.

((MoreUseful)х[1]) u; //

Нисх преобразование /RTTI ((MoreUseful)x[0]).u0; // Происходит исключение

}

} ///:-

Класс MoreUseful расширяет интерфейс класса Useful. Но благодаря наследованию он также может быть преобразован к типу Useful. Вы видите, как это происходит, при инициализации массива х в методе main. Так как оба объекта в массиве являются производными от Useful, вы можете послать сообщения (вызвать методы) f и д для обоих объектов, но при попытке вызова метода и (который существует только в классе MoreUseful) вы получите сообщение об ошибке компиляции.

Чтобы получить доступ к расширенному интерфейсу объекта MoreUseful, используйте нисходящее преобразование. Если тип указан правильно, все пройдет успешно; иначе произойдет исключение ClassCastException. Вам не понадобится писать дополнительный код для этого исключения, поскольку оно указывает на общую ошибку, которая может произойти в любом месте программы.

Впрочем, RTTI не сводится к простой проверке преобразований. Например, можно узнать, с каким типом вы имеете дело, прежде чем проводить нисходящее преобразование. Глава 11 полностью посвящена изучению различных аспектов динамического определения типов Java.

Резюме

Полиморфизм означает «многообразие форм». В объектно-ориентированном программировании базовый класс предоставляет общий интерфейс, а различные версии динамически связываемых методов — разные формы использования интерфейса.

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

Чтобы эффективно использовать полиморфизм — а значит, все объектно-ориентированные приемы — в своих программах, необходимо расширить свои представления о программировании, чтобы они охватывали не только члены и сообщения отдельного класса, но и общие аспекты классов, их взаимоотношения. Хотя это потребует значительных усилий, результат стоит того. Наградой станет ускорение разработки программ, улучшение структуры кода, расширяемые программы и сокращение усилий по сопровождению кода.

Интерфейсы

Интерфейсы и абстрактные классы улучшают структуру кода и способствуют отделению интерфейса от реализации.

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

Мы начнем с понятия

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

Абстрактные классы и методы

В примере с классами музыкальных инструментов из предыдущей главы методы базового класса Instrument всегда оставались «фиктивными». Попытка вызова такого метода означала, что в программе произошла какая-то ошибка. Это объяснялось тем, что класс Instrument создавался для определения общего интерфейса всех классов, производных от него.

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

Если в программе определяется абстрактный класс вроде Instrument, создание объектов такого класса практически всегда бессмысленно. Абстрактный класс создается для работы с набором классов через общий интерфейс. А если Instrument только выражает интерфейс, а создание объектов того класса не имеет смысла, вероятно, пользователю лучше запретить создавать такие объекты. Конечно, можно заставить все методы Instrument выдавать ошибки, но в этом случае получение информации откладывается до стадии выполнения. Ошибки такого рода лучше обнаруживать во время компиляции.

В языке Java для решения подобных задач применяются абстрактные методы1. Абстрактный метод незавершен; он состоит только из объявления и не имеет тела. Синтаксис объявления абстрактных методов выглядит так:

abstract void f;

Класс, содержащий абстрактные методы, называется абстрактным классом. Такие классы тоже должны помечаться ключевым словом abstract (в противном случае компилятор выдает сообщение об ошибке).

Если вы объявляете класс, производный от абстрактного класса, но хотите иметь возможность создания объектов нового типа, вам придется предоставить определения для всех абстрактных методов базового класса. Если этого не сделать, производный класс тоже останется абстрактным, и компилятор заставит пометить новый класс ключевым словом abstract.

Можно создавать класс с ключевым словом abstract даже тогда, когда в нем не имеется ни одного абстрактного метода. Это бывает полезно в ситуациях, где в классе абстрактные методы просто не нужны, но необходимо запретить создание экземпляров этого класса.

Класс Instrument очень легко можно сделать абстрактным. Только некоторые из его методов станут абстрактными, поскольку объявление класса как abstract не подразумевает, что все его методы должны быть абстрактными. Вот что получится:

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

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

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

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

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

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Эволюционер из трущоб. Том 3

Панарин Антон
3. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
6.00
рейтинг книги
Эволюционер из трущоб. Том 3

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

Винокуров Юрий
12. Кодекс Охотника
Фантастика:
боевая фантастика
городское фэнтези
аниме
7.50
рейтинг книги
Кодекс Охотника. Книга XII

Адвокат Империи 2

Карелин Сергей Витальевич
2. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Адвокат Империи 2

Идеальный мир для Лекаря 10

Сапфир Олег
10. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 10

Котенок. Книга 3

Федин Андрей Анатольевич
3. Котенок
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Котенок. Книга 3

Империя Хоста 3

Дмитрий
3. Империя Хоста
Фантастика:
боевая фантастика
попаданцы
5.50
рейтинг книги
Империя Хоста 3

Кодекс Крови. Книга I

Борзых М.
1. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга I

Вадбольский

Никитин Юрий Александрович
1. Вадбольский
Фантастика:
попаданцы
5.00
рейтинг книги
Вадбольский

Воспитание бабочек

Карризи Донато
Детективы:
триллеры
прочие детективы
5.00
рейтинг книги
Воспитание бабочек

Никчёмная Наследница

Кат Зозо
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Никчёмная Наследница

Имперский Курьер. Том 3

Бо Вова
3. Запечатанный мир
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Имперский Курьер. Том 3