![](/user_photo/2706_HbeT2.jpg)
- •Кен Арнольд Джеймс Гослинг Дэвид Холмс Язык программирования Java
- •Глава 1 первое знакомство с java 6
- •Глава 2 классы и объекты 29
- •Глава 3 расширение классов 47
- •Глава 4 интерфейсы 70
- •Глава 5 лексемы, операторы и выражения 78
- •Глава 6 порядок выполнения 105
- •Глава 7 исключения 113
- •Глава 8 строки 121
- •Глава 9 потоки 134
- •Глава 10 пакеты 156
- •Глава 11 пакет ввода/вывода 158
- •Глава 12 стандартные вспомогательные средства 183
- •Глава 13 применение типов в программировании 205
- •Глава 14 системное программирование 218
- •Глава1 первое знакомство сjava
- •1.1. С самого начала
- •1.2.Переменные
- •1.3. Комментарии
- •1.4.Именованные константы
- •1.4.1. Символы Unicode
- •1.5.Порядок выполнения
- •1.6.Классы и объекты
- •1.6.1.Создание объектов
- •1.6.2.Статические поля
- •1.6.3.Сборщик мусора
- •1.7.Методы и параметры
- •1.7.1.Вызов метода
- •1.7.2.Ссылка this
- •1.7.3.Статические методы
- •1.8.Массивы
- •1.9.Строковые объекты
- •1.10.Расширение класса
- •1.10.1.Класс Object
- •1.10.2.Вызов методов суперкласса
- •1.11. Интерфейсы
- •1.12.Исключения
- •1.13.Пакеты
- •1.14.Инфраструктура Java
- •1.15.Прочее
- •Глава 2 классы и объекты
- •2.1. Простой класс
- •2.2. Поля
- •2.3. Управление доступом и наследование
- •2.4. Создание объектов
- •2.5. Конструкторы
- •2.6. Методы
- •2.6.1. Значения параметров
- •2.6.2. Применение методов для ограничения доступа
- •2.7. Ссылка this
- •2.8. Перегрузка методов
- •2.9. Статические члены
- •2.9.1. Блоки статической инициализации
- •2.9.2. Статические методы
- •2.10. Сборка мусора и метод finalize
- •2.10.1. Метод finalize
- •2.10.2. Восстановление объектов в методе
- •2.11. Метод main
- •2.12. Метод toString
- •2.13. Родные методы
- •Глава 3 расширение классов
- •3.1. Расширенный класс
- •3.2. Истинное значение protected
- •3.3. Конструкторы в расширенных классах
- •3.3.1. Порядок вызова конструкторов
- •3.4. Переопределение методов и скрытие полей
- •3.4.1. Ключевое слово super
- •3.5. Объявление методов и классов с ключевым словом final
- •3.6. Класс Object
- •3.7. Абстрактные классы и методы
- •3.8. Дублирование объектов
- •3.9. Расширение классов: когда и как
- •3.10. Проектирование расширяемого класса
- •Глава 4 интерфейсы
- •4.1. Пример интерфейса
- •4.2. Одиночное и множественное наследование
- •4.3. Расширение интерфейсов
- •4.3.1. Конфликты имен
- •4.4. Реализация интерфейсов
- •4.5. Использование реализации интерфейса
- •4.6. Для чего применяются интерфейсы
- •Глава 5 лексемы, операторы и выражения
- •5.1. Набор символов
- •5.2. Комментарии
- •5.3. Лексемы
- •5.4. Идентификаторы
- •5.4.1. Зарезервированные слова Java
- •5.5. Примитивные типы
- •5.6. Литералы
- •5.6.1. Ссылки на объекты
- •5.6.2. Логические значения
- •5.6.3. Целые значения
- •5.6.4. Значения с плавающей точкой
- •5.6.5. Символы
- •5.6.6. Строки
- •5.7. Объявления переменных
- •5.7.1. Значение имени
- •5.8. Массивы
- •5.8.1. Многомерные массивы
- •5.9. Инициализация
- •5.9.1. Инициализация массивов
- •5.10. Приоритет и ассоциативность операторов
- •5.11. Порядок вычислений
- •5.12. Тип выражения
- •5.13. Приведение типов
- •5.13.1. Неявное приведение типов
- •5.13.2. Явное приведение и instanceof
- •5.13.3. Строковое приведение
- •5.14. Доступ к членам
- •5.15. Арифметические операторы
- •5.15.1. Целочисленная арифметика
- •5.15.2. Арифметика с плавающей точкой
- •5.15.3. Арифметика с плавающей точкой и стандарт ieee-754
- •5.15.4. Конкатенация строк
- •5.16. Операторы приращения и уменьшения
- •5.17. Операторы отношения и условный оператор
- •5.18. Поразрядные операции
- •5.19. Условный оператор
- •5.20. Операторы присваивания
- •5.21. Имена пакетов
- •Глава 6 порядок выполнения
- •6.1. Операторы и блоки
- •6.2. Оператор if-else
- •6.3. Оператор switch
- •6.4. Цикл while и do-while
- •6.5. Оператор for
- •6.6. Метки
- •6.7. Оператор break
- •6.8. Оператор continue
- •6.9. Оператор return
- •Глава 7 исключения
- •7.1. Создание новых типов исключений
- •7.2. Оператор throw
- •7.3. Условие throws
- •7.4. Операторы try, catch и finally
- •7.4.1. Условие finally
- •7.5. Когда применяются исключения
- •Глава 8 строки
- •8.1. Основные операции со строками
- •8.2. Сравнение строк
- •8.3. Вспомогательные методы
- •8.4. Создание производных строк
- •8.5. Преобразование строк
- •8.6. Строки и символьные массивы
- •8.7. Строки и массивы byte
- •8.8. Класс StringBuffer
- •8.8.1. Модификация буфера
- •8.8.2. Извлечение данных
- •8.8.3. Работа с емкостью буфера
- •Глава 9 потоки
- •9.1. Создание потоков
- •9.2. Синхронизация
- •9.2.1. Методы synchronized
- •9.2.2. Операторы synchronized
- •9.3. Методы wait и notify
- •9.4. Подробности, касающиеся wait и notify
- •9.5. Планирование потоков
- •9.6. Взаимная блокировка
- •9.7. Приостановка потоков
- •9.8. Прерывание потока
- •9.9. Завершение работы потока
- •9.10. Завершение приложения
- •9.11. Использование Runnable
- •9.12. Ключевое слово volatile
- •9.13. Безопасность потоков и ThreadGroup
- •9.14. Отладка потоков
- •Глава 10 пакеты
- •10.1. Имена пакетов
- •10.2. Пакетный доступ
- •10.3. Содержимое пакета
- •Глава 11 пакет ввода/вывода
- •11.1. Потоки
- •11.2. Класс InputStream
- •11.3. Класс OutputStream
- •11.4. Стандартные типы потоков
- •11.5. Фильтрующие потоки
- •11.6. Класс PrintStream
- •11.7. Буферизованные потоки
- •11.8. Байтовые потоки
- •11.9. Класс StringBufferInputStream
- •11.10. Файловые потоки и FileDescriptor
- •11.11. Конвейерные потоки
- •11.12. Класс Seq uenceInputStream
- •11.13. Класс LineNumberInputStream
- •11.14. Класс PushbackInputStream
- •11.15. Класс StreamTokenizer
- •11.16. Потоки данных
- •11.16.1. Классы потоков данных
- •11.17. Класс RandomAccessFile
- •11.18. Класс File
- •11.19. Интерфейс FilenameFilter
- •11.20. Классы ioException
- •Глава 12 стандартные вспомогательные средства
- •12.1. Класс BitSet
- •12.2. Интерфейс Enumeration
- •12.3. Реализация интерфейса Enumeration
- •12.4. Класс Vector
- •12.5. Класс Stack
- •12.6. Класс Dictionary
- •12.7. Класс Hashtable
- •12.8. Класс Properties
- •12.9. Классы Observer/Observable
- •12.10. Класс Date
- •12.11. Класс Random
- •12.12. Класс String Tokenizer
- •Глава 13 применение типов в программировании
- •13.1. Класс Class
- •13.2. Загрузка классов
- •13.3. Классы-оболочки: общий обзор
- •13.4. Класс Boolean
- •13.5. Класс Character
- •13.6. Класс Number
- •13.7. Класс Integer
- •13.8. Класс Long
- •13.9. Классы Float и Double
- •Глава 14 системное программирование
- •14.1. Стандартный поток ввода/вывода
- •14.2. Управление памятью
- •14.3. Системные свойства
- •14.4. Создание процессов
- •14.5. Класс Runtime
- •14.6. Разное
- •14.7. Безопасность
- •14.8. Класс Math
- •Приложение а Родные методы
- •А.1 Обзор
- •А.2.1 Имена
- •А.2.2 Методы
- •А.2.3 Типы
- •А.2.5 Средства безопасности
- •А.2.6 Работа с памятью
- •А.3 Пример
- •А.3.1 Внутреннее строение LockableFile
- •А.4 Строки
- •А.5 Массивы
- •А.6 Создание объектов
- •А.7 Вызов методов Java
- •А.8 Последнее предупреждение
- •Приложение б Runtime-исключения в Java
- •Б.1 Классы RuntimeException
- •Б.2 Классы Error
- •Приложение в Полезные таблицы
3.1. Расширенный класс
Каждый класс из тех, что встречались нам в этой книге, является расширенным, независимо от того, объявлен ли он с ключевым словом extends или нет. Даже такие классы, как Body, которые вроде бы не расширяют других классов, на самом деле неявно происходят от принадлежащего Java класса Object. Другими словами, Object находится в корне всей иерархии классов. В нем объявляются методы, которые реализованы во всех объектах. Переменные типа Object могут ссылаться на любые объекты, будь это экземпляры класса или массивы.
Например, при разработке класса для списка, элементы которого могут быть объектами произвольного типа, можно предусмотреть в нем поле типа Object. В такой список не могут входить значения примитивных типов (int, boolean и т.д.), однако при необходимости можно создать объекты этих типов спомощью классов-оболочек (Integer, Boolean и т.д.), описанных в главе 13.
Для демонстрации работы с подклассами начнем с базового класса для хранения атрибутов, представленных в виде пар имя/значение. Имена атрибутов являются строками (например, “цвет” или “расположение”). Атрибуты могут иметь произвольный тип, поэтому их значения хранятся в переменных типа Object:
class Attr {
private String name;
private Object value = null;
public Attr(String nameOf) {
name = nameOf;
}
public Attr(String nameOf, Object valueOf) {
name = nameOf;
value = valueOf;
}
public String nameOf() {
return name;
}
public Object valueOf() {
return value;
}
public Object valueOf(Object newValue) {
Object oldVal = value;
value = newValue;
return oldVal;
}
}
Каждому атрибуту обязательно должно быть присвоено имя, поэтому при вызове конструкторов Attr им передается параметр-строка. Имя должно быть доступно только для чтения, поскольку оно может применяться, скажем, в качестве ключа хеш-таблицы или сортированного списка. Если при этом имя атрибута будет изменено за пределами класса, то объект-атрибут “потеряется”, так как в таблице или списке он будет храниться под старым именем. Значение атрибута можно менять в любой момент.
Следующий класс расширяет понятие атрибута для хранения цветовых атрибутов, которые могут быть строками, служащими для именования или описания цветов. Описания цветов могут представлять собой как названия (“красный” или “бежевый”), по которым необходимо найти нужное значение в таблице, так и числовые значения, которые могут преобразовываться в стандартное, более эффективное представление ScreenColor (которое, как предполагается, определено в другом месте программы). Преобразование описания в объект ScreenColor сопряжено с большими накладными расходами, так что для каждого атрибута эту операцию желательно выполнять только один раз. Для этого мы расширяем класс Attr и создаем на его основе класс ColorAttr, включающий специальный метод для получения преобразованного объекта ScreenColor. Данный метод реализован так, что преобразование выполняется всего один раз:
class ColorAttr extends Attr {
private ScreenColor myColor; // преобразованный цвет
public ColorAttr(String name, Object value) {
super(name, value);
decodeColor();
}
public ColorAttr(String name) {
this(name, “transparent”);
}
public ColorAttr(String name, ScreenColor value) {
super(name, value.toString());
myColor = value;
}
public Object valueOf(Object newValue) {
// сначала выполнить метод valueOf() суперкласса
Object retval = super.valueOf(newValue);
decodeColor();
return retval;
}
/** Присвоить атрибуту ScreenColor значение,
а не описание */
public ScreenColor valueOf(ScreenColor newValue) {
// сначала выполнить метод valueOf() суперкласса
super.valueOf(newValue.toString());
myColor = newValue;
return newValue;
}
/** Вернуть преобразованный объект ScreenColor */
public ScreenColor color() {
return myColor;
}
/** Задать ScreenColor по описанию в valueOf */
protected void decodeColor() {
if (valueOf() == null)
myColor = null;
else
myColor = new ScreenColor(valueOf());
}
}
Сначала мы создаем новый класс ColorAttr, расширяющий класс Attr. Основные функции класса ColorAttr те же, что и у класса Attr, но к ним добавляется несколько новых. Класс Attr является суперклассом по отношению к ColorAttr, а ColorAttr— подклассом по отношению к Attr. Иерархия классов для нашего примера выглядит следующим образом (суперкласс на диаграмме расположен выше своего подкласса):
Расширенный класс ColorAttr выполняет три основные функции:
Он обеспечивает наличие трех конструкторов: два из них копируют поведение суперкласса, а третий позволяет сразу передать объект Screen Color.
Он перегружает и переопределяет метод valueOf базового класса, чтобы при изменении значения атрибута создался объект ScreenColor.
Он включает новый метод color для возврата цветового описания, преобразованного в объект ScreenColor.
Упражнение 3.1
На основе класса Vehicle из главы2 создайте расширенный класс с именем PassengerVehicle и наделите его возможностью определения числа свободных и занятых мест в машине. Включите в PassengerVehicle новый метод main, который создает несколько объектов и выводит их.