Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Создание обобщенного метода. Обобщенные конструкторы




Создание обобщенного метода

Как было показано в предыдущих примерах, методы внутри обобщенного класса могут использовать параметр-класс, и, следовательно, обобщения касаются также параметров методов. Однако можно объявить обобщенный метод, который сам по себе использует один или более параметров типов. Более того, можно объявить обобщенный метод, который включен в не параметризованный (необобщенный) класс.

Начнем с примера. В следующей программе объявлен необобщенный класс по имени GenMethDemo и статический обобщенный метод внутри класса по имени isIn(). Метод isIn() определяет, является ли объект членом массива. Он может быть использован с любым типом объектов и массивов до тех пор, пока массив содержит объекты, совместимые с типом искомого объекта.

// Демонстрация простого обобщенного метода.

class GenMethDemo {

// Определение, содержится ли объект в массиве.

static < T, V extends T> boolean isIn(T x, V[] y) {

for(int i=0; i < y. length; i++)

if(x. equals(y[i])) return true;

return false;

}

BookNew_JAVA-7. indb 356 02. 06. 2007 1: 07: 13

Глава 14. Обобщения 357

public static void main(String args[]) {

// Применение isIn() для Integer.

Integer nums[] = { 1, 2, 3, 4, 5 };

if(isIn(2, nums))

System. out. println(" 2 содержится в nums" );

if(! isIn(7, nums))

System. out. println(" 7 не содержится в nums" );

System. out. println();

// Применение isIn() для String.

String strs[] = { " один", " два", " три",

" четыре", " пять" };

if(isIn(" два", strs))

System. out. println(" два содержится в strs" );

if(! isIn(" семь", strs))

System. out. println(" семь содержится в strs" );

// Не скомпилируется! Типы должны быть совместимыми.

// if(isIn(" два", nums))

// System. out. println(" два содержится в strs " );

}}

Результат работы этой программы показан ниже:

2 содержится в nums

7 не содержится в nums

два содержится в strs

семь не содержится в strs

Рассмотрим isIn() поближе. Для начала посмотрите, как объявлен метод в следующей строке:

static < T, V extends T> boolean isIn(T x, V[] y) {

Параметр типа объявлен перед типом возврата метода. Второе — тип V ограничен сверху типом T. То есть V либо должен тем же типом, что и T, либо типом его подклассов.

Это отношение указывает, что isIn() может быть вызван только с аргументами, совместимыми между собой. Также обратите внимание, что метод isIn() статический, что позволяет вызывать его независимо от какого-либо объекта. Однако ясно, что обобщенные методы могут быть как статическими, так и нестатическими. Нет никаких ограничений на этот счет.

Теперь обратите внимание на то, как isIn() вызывается внутри main() — с нормальным синтаксисом вызовов, без необходимости специфицировать аргументы типа. Это потому, что типы аргументов подразумеваются автоматически, и типы T и V определяются соответственно. Например, в следующем вызове:

if(isIn(2, nums))

, тип первого аргумента — Integer (благодаря автоупаковке), что подставляет Integer вместо T. Базовый тип второго аргумента — также Integer, что подставляет его и вместо V.

Во втором вызове используются типы String, и вместо типов T и V подставляются String.

Теперь обратите внимание на закомментированный код:

// if(isIn(" два", nums))

// System. out. println(" два содержится в strs " );

Если вы уберете комментарии с этих строк и затем попытаетесь скомпилировать программу, то получите ошибку. Причина в том, что тип параметра V ограничен T конструкцией extends в объявлении V. Это значит, что V должно иметь либо тип T, либо тип его подкласса. А в этом случае первый аргумент имеет тип String, но второй — Integer, который не является подклассом String. Это вызовет ошибку несоответствия типов во время компиляции. Такая способность обеспечивать безопасность типов — одно из наиболее существенных преимуществ обобщенных методов.

Синтаксис, использованный для создания isIn(), можно обобщить. Вот синтаксис обобщенного метода:

< type-param-list> ret-type meth-name(param-list) { //...

Во всех случаях type-param-list — это разделенный запятыми список параметров типа. Обратите внимание, что для обобщенного метода список параметров типа предшествует типу возврата.

Обобщенные конструкторы

Конструкторы также могут быть обобщенными, даже если их классы таковыми не являются. Например, рассмотрим следующую короткую программу:

// Использование обобщенного конструктора.

class GenCons {

private double val;

< T extends Number> GenCons(T arg) {

val = arg. doubleValue();

}

void showval() {

System. out. println(" val: " + val);

}}

class GenConsDemo {

public static void main(String args[]) {

GenCons test = new GenCons(100);

GenCons test2 = new GenCons(123. 5F);

test. showval();

test2. showval();

}}

Вывод этой программы:

val: 100. 0

val: 123. 5

Поскольку GenCons() специфицирует параметр обобщенного типа, который может быть подклассом Number, GenCons() можно вызывать с любым числовым типом, включая Integer, Float или Double. Таким образом, даже несмотря на то, что GenCons — необобщенный класс, его конструктор обобщен.

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...