
- •Программирование на Java
- •Глава 1 Введение в java. Основы языка.
- •Тема 1.1 Язык программирования java.
- •Тема 1.2 Состав пакета Java2.
- •Тема 1.3 Настройка среды окружения.
- •Тема 1.4 Структура Java-программы.
- •Тема 1.5 Набор текста, запуск и компиляция простейшей программы.
- •Тема 1.6 Подробное рассмотрение кода простейшей программы.
- •Тема 1.7. Создание программы в разных средах разработки.
- •Тема 1.8 Лексические основы языка
- •Тема 1.9 Элементарные типы данных.
- •Тема 1.10 Преобразование типов.
- •Арифметические операции
- •Операции сравнения
- •Тема 1.11 Кoнсольный ввод с помощью класса java.Util.Scanner
- •Тема 1.12 Классы-оболочки
- •Тема 1.13 Автоупакока и автораспаковка.
- •Тема 1.14 Операторы
- •1.14.1 Блок
- •1.14.2 Условный оператор if
- •1.14.4 Оператор цикла while
- •1.14.5 Оператор цикла do-while
- •1.14.6 Оператор цикла for
- •1.14.7 Оператор continue и метки
- •1.14.8 Оператор break
- •1.14.9 Оператор варианта switch
- •Тема 1.15 Статический импорт
- •Тема 1.16 Класс Math
- •Задания
- •Тема 1.17 Псевдослучайные числа
- •Тема 1.18 Генерация случайных чисел
- •Тема 1.19 Массивы в Java
- •1.19.1 Объявление и заполнение массива
- •1.19.2 Сортировка массива
- •Сортировка выбором
- •Сортировка методом пузырька
- •1.19.3 Многомерные массивы
- •Задания
- •1.19.4 Нерегулярные массивы
- •Глава 2 классы
- •Тема 2.1 Основы классов
- •Тема 2.2 Общая форма класса
- •Тема 2.3 Объявление объектов
- •Тема 2.4 Более подробное рассмотрение операции new
- •Тема 2.5 Присваивание переменных объектных ссылок
- •Тема 2.6 Знакомство с методами
- •Тема 2.7 Возвращение значения из метода
- •Тема 2.8 Добавление метода, принимающего параметры
- •Тема 2.9 Конструкторы
- •Тема 2.10 Сборка мусора
- •Тема 2.11 Перегрузка методов
- •Тема 2.12 Перегрузка конструкторов
- •Тема 2.13 Использование объектов в качестве параметров
- •Тема 2.14 Более пристальный взгляд на передачу аргументов
- •Тема 2.16 Рекурсия
- •Тема 2.17 Введение в управление доступом
- •Тема 2.18 Ключевое слово static
- •Тема 2.19 Ключевое слово final
- •Тема 2.20 Аргументы переменной длины
- •Тема 2.21 Строки и числа
- •Тема 2.22 Нумерованные типы
- •Глава 3 наследование и интерфейсы
- •Тема 3.1 Основы наследования
- •Тема 3.2 Наследование и доступ к членам класса
- •Тема 3.3 Конструкторы и наследование
- •Тема 3.4 Использование ключевого слова super для вызова конструктора суперкласса
- •Тема 3.5 Использование ключевого слова super для доступа к членам суперкласса
- •Тема 3.6 Многоуровневая иерархия
- •Тема 3.7 Когда вызываются конструкторы
- •Тема 3.8 Объекты подклассов и ссылки на суперклассы
- •Тема 3.9 Переопределение методов
- •Тема 3.10 Переопределение методов и поддержка полиморфизма
- •Тема 3.11 Использование абстрактных классов
- •Тема 3.12 Использование ключевого слова final
- •Тема 3.13 Предотвращение переопределения методов
- •Тема 3.14 Предотвращение наследования
- •Тема 3.15 Класс Object
- •Тема 3.16 Интерфейсы
- •3.16.1 Объявление интерфейса.
- •3.16.2 Реализация интерфейсов
- •3.16.3 Использование ссылок на интерфейсы
- •3.16.4 Переменные в составе интерфейсов
- •3.16.5 Наследование интерфейсов
- •Тема 3.17 Пакеты и ограничение доступа
- •Тема 3.18 Внутренние классы
- •3.18.1 Внутренние (inner) классы
- •3.18.2 Вложенные (nested) классы
- •3.18.3 Анонимные (anonymous) классы
- •Глава 4 Обработка исключительных ситуаций
- •Тема 4.1 Исключения в Java
- •Тема 4.2 Типы исключений
- •Тема 4.3 Неперехваченные исключения
- •Тема 4.4 Ключевые слова try и catch
- •Тема 4.6 Ключевое слово throw
- •Тема 4.7 Ключевое слово throws
- •Тема 4.8 Ключевое слово finally
- •Ошибка при выполнении метода1 java.Lang.ArithmeticException: Demo
- •Тема 4.9 Потомки Exception или написание своих классов ошибок
- •Глава 5 Универсальные типы. КоллекциИ
- •Тема 5.1 Общие сведения об универсальных типах
- •Тема 5.2 Универсальный класс с двумя параметрами типа
- •Тема 5.3 Ограниченные типы
- •Тема 5.4 Использование групповых параметров
- •Тема 5.5 Универсальные методы
- •Тема 5.6 Универсальные интерфейсы
- •Тема 5.7 Ошибки неоднозначности
- •Тема 5.8 Ограничения универсальных типов
- •Тема 5.9 Краткий обзор коллекций
- •5.9.1 Класс ArrayList
- •5.9.2 Класс LinkedList
- •5.9.3 Класс HashSet
- •5.9.4 Класс TreeSet
- •5.9.5 Доступ к коллекции через итератор
- •5.9.6 Алгоритмы коллекций
- •Глава 6 jdbc (Java DataBase Connectivity) Тема 6.1 Драйверы, соединения и запросы
- •Тема 6.2 Простое соединение и простой запрос
- •Тема 6.2 Класс ResultSet
- •Тема 6.3 Метаданные
- •Тема 6.4 Подготовленные запросы
- •Глава 7 Swing и пользовательский интерфейс
- •Тема 7.1 Общие сведения о swing
- •Тема 7.2 Архитектура mvc
- •Тема 7.3 Контейнер и компоненты
- •Тема 7.4 Простая программа, использующая средства Swing
- •Тема 7.5 Поддержка событий
- •Тема 7.6 Использование кнопок и обработка событий
- •Тема 7.7 Краткие сведения о диспетчерах компоновки
- •Тема 7.8 Пример использования jdbc и swing вместе
Тема 5.4 Использование групповых параметров
Рассмотренные выше варианты универсальных типов удобны в работе, но в ряде случаев приходится отдавать предпочтение другим конструкциям. Предположим, что нам надо реализовать метод absEqual( ), который возвращал бы значение true в случае, если два объекта NumericFns (этот класс был рассмотрен ранее) содержат одинаковые значения. Предположим также, что нам необходимо, чтобы этот метод работал с любыми типами данных, которые могут храниться в сравниваемых объектах. Например, если один объект содержит значение 1,25 типа Double, а второй - значение -1,25 типа Float, метод absEqual() должен возвращать значение true. Один из способов реализации absEqual() состоит в том, чтобы передавать Методу параметр типа NumericFns, а затем сравнивать его абсолютное значение с абсолютным значением текущего объекта и возвращать true, если эти значения совпадают. Например, вызов absEqual() может выглядеть следующим образом:
NumericFns<Double> dOb = new NumericFns<Double>(1.25);
NumericFns<Float> fOb = new NumericFns<Float>(-1.25);
if(dOb.absEqual (fOb) )
System.out.println("Absolute values are the same.");
else
System.out.println("Absolute values differ.");
Ha первый взгляд кажется, что при работе с absEqual( ) не возникают никакие проблемы. Однако это не так. Неприятности начнутся сразу же, как только вы попытаетесь объявить параметр типа NumericFns. Каким он должен быть? Подходящим кажется решение наподобие следующего, где в качестве параметра типа задается Т:
// Программа работает некорректно!
// Определение равенства абсолютных значений двух объектов,
public boolean absEqual(NumericFns<T> ob) {
if(Math.abs(num.doubleValue()) == Math.abs(ob.num.doubleValue())
return true;
else
return false;
}
В данном случае для определения абсолютного значения каждого числа используется стандартный метод Math.abs( ). Полученные значения сравниваются. Проблема состоит в том, что описанный подход будет действовать только тогда, когда объект NumericFns, передаваемый в качестве параметра, имеет тот же тип, что и текущий объект. Например, если текущий объект принадлежит типу NumericFns<Integer>, параметр ob также должен быть типа NumericFns<Integer>. Сравнить текущий объект с объектом типа NumericFns<Double> невозможно. Таким образом, решение не является универсальным.
Для того чтобы создать метод absEqual(), применимый во всех случаях, вам надо использовать еще одно средство, связанное с универсальными типами, – групповой параметр. В качестве такого параметра используется символ ?, который представляет неизвестный тип. Используя данное средство, метод absEqual() можно переписать так:
// Определение равенства абсолютных значений двух объектов,
public boolean absEqual(NumericFns<?> ob) {
if(Math.abs(num.doubleValue()) == Math.abs(ob.num.doubleValue()))
return true;
else
return false;
}
Здесь выражение NumericFns<?> соответствует любому типу NumericFns и позволяет сравнивать абсолютные значения двух произвольных объектов NumericFns.
Листинг 5.4
// Использование группового параметра
public class NumericF<T extends Number> {
private T num;
public NumericF(T n) {
num = n;
}
public double reciprocal() {
return 1 / num.doubleValue();
}
public double fraction() {
return num.doubleValue() - num.intValue();
}
public boolean absEqual(NumericF<?> ob) {
if (Math.abs(num.doubleValue())
== Math.abs(ob.num.doubleValue())) {
return true;
} else {
return false;
}
}
}
// Демонстрация использования группового параметра
public class WildcardDemo {
public static void main(String args[]) {
NumericF<Integer> iOb = new NumericF<Integer>(6);
NumericF<Double> dOb = new NumericF<Double>(-6.0);
NumericF<Long> lOb = new NumericF<Long>(5L);
System.out.println("Testing iOb and dOb.");
if (iOb.absEqual(dOb)) // групповой тип соответствует Double
{
System.out.println("Absolute values are equal.");
} else {
System.out.println("Absolute values differ.");
}
System.out.println();
System.out.println("Testing iOb and lOb.");
if (iOb.absEqual(lOb)) // групповой тип соответствует Long
{
System.out.println("Absolute values are equal.");
} else {
System.out.println("Absolute values differ.");
}
}
}
Обратите внимание на следующие два вызова absEqual():
if (iOb.absEqual(dOb))
if(iOb.absEqual(lOb))
В первом выражении iOb – это объект типа NumericF< Integer>, a dOb - объект типа NumericF<Double>. Благодаря использованию группового параметра становится возможным передать dOb методу absEqual(). Подобным образом формируется и другой вызов, в котором методу передается объект типа NumericF<Long>.
Важно понимать, что групповые параметры не влияют на то, какой тип объекта NumericF может быть создан. Этим управляет выражение extends в объявлении NumericF. Групповой параметр лишь указывает на соответствие любому объекту NumericF.