Java руководство для начинающих - Шилдт Герберт (2012)
-
Год:2012
-
Название:Java руководство для начинающих
-
Автор:
-
Жанр:
-
Оригинал:Английский
-
Язык:Русский
-
Издательство:Вильямс
-
Страниц:316
-
ISBN:978-5-8459-1770-6
-
Рейтинг:
-
Ваша оценка:
Java руководство для начинающих - Шилдт Герберт читать онлайн бесплатно полную версию книги
Paircinteger, Integer> х = new Pair(l, 2);
//И эта строка кода верна, так как Integer является подклассом Number.
Pair у = new Pair(10.4, 12);
А следующий фрагмент кода содержит ошибку:
// Эта строка кода недопустима, так как String не является подклассом Number.
Pair z = new Pair(10.4, "12");
В данном случае класс String не является производным от класса Number, что нарушает граничное условие, указанное в объявлении класса Pair.
## Использование метасимвольных аргументов
Несмотря на всю полезность типовой безопасности в обобщениях, иногда она может помешать использованию идеально подходящих языковых конструкций. Допустим, требуется реализовать метод absEqual (), возвращающий логическое значение true в том случае, если два объекта рассмотренного выше класса NumericFns содержат одинаковые абсолютные значения. Допустим также, что этот метод должен оперировать любыми типами числовых данных, которые могут храниться в сравниваемых объектах. Так, если один объект содержит значение 1,25 типа Double, а другой — значение -1,25 типа Float, метод absEqual () должен возвращать логическое значение true. Один из способов реализации метода absEqual () состоит в том, чтобы передавать этому методу параметр типа NumericFns, а затем сравнивать его абсолютное значение с абсолютным значением текущего объекта и возвращать логическое значение true, если эти значения совпадают. Например, вызов метода absEqual () может выглядеть следующим образом:
NumericFns dOb = new NumericFns(1.25) ;
NumericFns fOb = new NumericFns(-1.25) ;
if(dOb.absEqual(fOb))
System.out.println("Absolute values are the same.");
else
System.out.println("Absolute values differ.");
На первый взгляд может показаться, что при выполнении метода absEqual () не должно возникнуть никаких затруднений, но это совсем не так. Затруднения начнутся при первой же попытке объявить параметр типа NumericFns. Каким он должен быть? Казалось бы, подходящим должно быть следующее решение, где т указывается в качестве параметра типа:
//Не пройдет!
// определить равенство абсолютных значений в двух объектах
boolean absEqual(NumericFns ob) {
if(Math.abs(num.doubleValue()) ==
Math.abs(ob.num.doubleValue()) return true;
return false;
}
В данном случае для определения абсолютного значения каждого числа используется стандартный метод Math. abs (). Полученные значения сравниваются. Но дело в том, что рассматриваемое здесь решение окажется пригодным лишь в том случае, если объект класса NumericFns, передаваемый в качестве параметра, имеет тот же тип, что и текущий объект. Так, если текущий объект относится к типу NumericFns<Integer>, параметр ob также должен быть типа NumericFns<Integer>, а следовательно, сравнить текущий объект с объектом типа NumericFns<Double> не удастся. Таким образом, выбранное решение не является обобщенным.
Для того чтобы создать обобщенный метод absEqual (), придется воспользоваться еще одним свойством обобщений в Java, называемым метасимвольным аргументом. Для указания такого аргумента служит знак ?, обозначающий неизвестный тип данных. Используя метасимвольный аргумент, можно переписать метод absEqual () следующим образом:
// определить равенство абсолютных значений в двух объектах
boolean absEqual(NumericFns<?> ob) { // обратите внимание на метасимвол
if(Math.abs(num.doubleValue()) ==
Math.abs(ob.num.doubleValue()) return true;
return false;
}
В данном случае выражение NumericFns<?> соответствует любому типу объекта из класса NumericFns и позволяет сравнивать абсолютные значения в двух произвольных объектах класса NumericFns. Ниже приведен пример программы, демонстрирующий применение метасимвольного аргумента.
// Применение метасимвольного аргумента,
class NumericFns {
T num;