Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Форум на вашем ... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Содержание сайт... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Создание отчето... 65457
Модуль Forms 65217
Пример работы с... 64701
ТЕХНОЛОГИИ ДОСТ... 61904
Имитационное мо... 57784
Реклама
Сейчас на сайте
Гостей: 5
На сайте нет зарегистрированных пользователей

Пользователей: 13,085
новичок: nikita222dolban
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Моделирование интернет магазина (Apache, Php, Html) на GPSS + Блок схема
Моделирование работы узла коммутации сообщений на GPSS + Пояснительная з...
База данных электронного документооборота на Delphi + бд Intebase

Реклама



Подписывайся на YouTube канал о программировании, что бы не пропустить новые видео!

ПОДПИСЫВАЙСЯ на канал о программировании
Ограниченные типы
В предыдущих примерах параметры типа могли заменяться классами любого типа. В большинстве случаев это замечательно, но иногда полезно ограничить количество типов, которые можно передавать параметру типа. Например, Вы хотите создать настраиваемый класс, который содержит метод, возвращающий среднее арифметическое элементов числового массива. Более того, хотите использовать этот класс для получения среднего арифметического элементов массивов разных числовых типов, включая целые, числа с плавающей запятой и двойной точности. Следовательно, следует задать тип элементов массива в общем виде с помощью параметра типа. Для создания такого класса можно попытаться написать код, похожий на приведенный в листинге 3.4.
Листинг 3.4. Неудачная попытка создать настраиваемый класс дли вычисления среднего арифметического элементов массива любого заданного числового типа

// Класс содержит ошибку!
class Stats {
T[] nums;
// передает конструктору ссылку на
// массив типа Т.
Stats(T[] o) {
nums = o;
}
// Возвращает тип double во всех cлучаях,
double average() {
double sum = 0.0;

for(int i=0; i < nums.length; i++)
sum += nums[i].doubleValue(); // Error!!!

return sum / nums.length;
}
}



В классе Stats метод average() пытается получить все элементы массива num, приведенные к типу double с помощью метода doubleValue (). Поскольку все числовые классы, такие как Integer и Double, являются подклассами класса Number, а в классе Number определен метод doubleValue(), этот метод доступен для всех числовых классов-оболочек. Но проблема состоит в том, что компилятор ничего не знает о Вашем намерении создавать объекты типа Stats, используя только числовые типы для замены параметра типа т. Более того, Вам нужно каким-либо способом обеспечить действительную передачу только числовых типов. Для обработки подобных ситуаций язык Java предлагает ограниченные типы (bounded types). При объявлении параметра типа Вы можете задать верхнюю границу, определяющую суперкласс, от которого должны быть унаследованы все аргументы типа. Такое ограничение устанавливается с помощью ключевого слова extends при описании параметра типа, как показано в следующей строке:
<Т extends superclass>
Приведенное объявление указывает на то, что параметр T можно заменить только типом superclass или его подклассами (производными от него классами). Таким образом, superclass задает верхнюю границу включительно.
Вы можете использовать суперкласс Number как верхнюю границу для настройки класса Stats, описанного ранее (листинг 3.5).
Листинг 3.5. Использование ограниченного типа при объявлении класса Stats
// В этой версии класса Stats, аргумент типа для
// Т должен быть Number, или производный
// от Number класс.
class Stats {
T[] nums; // массив типа Number или его подкласса
// Передает конструктору ссылку на
// массив типа Number или его подкласса.
Stats(T[] o) {
nums = o;
}
// Возвращает тип double в любом случае.
double average() {
double sum = 0.0;

for(int i=0; i < nums.length; i++)
sum += nums[i].doubleValue();

return sum / nums.length;
}
}
// Демонстрирует применение класса Stats.
class BoundsDemo {
public static void main(String args[]) {

Integer inums[] = { 1, 2, 3, 4, 5 };
Stats iob = new Stats(inums);
double v = iob.average();
System.out.println("iob average is " + v);

Double dnums[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
Stats dob = new Stats(dnums);
double w = dob.average();
System.out.println("dob average is " + w);
// Эти строки не будут компилироваться,так как String
// не является подклассом суперкласса Number.
// String strs[] = { "1", "2", "3", "4", "5" };
// Stats strob = new Stats(strs);
// double x = strob.average() ;
// System.out.printlnf"strob average is " + v);
}
}



Далее приведен вывод результатов работы программы из листинга 3.5.
Average is 3.0
Average is 3.3



Обратите внимание на новое объявление класса Stats, приведенное в следующей строке: class Stats {
Поскольку теперь тип т ограничен суперклассом Number, компилятор языка Java знает, что все объекты типа т могут вызывать метод doubleValue(), определенный в суперклассе Number. Это само по себе значительное преимущество. Но кроме этого, ограничение типа т препятствует созданию нечисловых объектов типа Stats. Если удалить символы комментария из заключительных строк листинга 3.5, а затем выполнить компиляцию, Вы получите ошибки на этапе компиляции, так как тип String не является подклассом суперкласса Number.
Применение метасимвольных аргументов
Как ни полезна безопасность типов, иногда она может мешать формированию вполне приемлемых конструкций. Предположим, что в имеющийся класс Stats, описанный в предыдущем разделе, Вы хотите добавить метод sameAvg() который определяет, содержатся ли в двух объектах Stats массивы с одинаковым значением среднего арифметического, независимо от типа числовых данных массивов. Например, если один объект содержит значения 1.0, 2.0 и 3.0 типа double, а второй целые числа 1, 2 и 3, средние арифметические массивов будут одинаковы. Один из способов реализации метода sameAvg( ) — передача в класс Stats аргумента, последующее сравнение среднего арифметического этого аргумента со средним арифметическим объекта, вызвавшего метод, и возврат значения true, если средние арифметические одинаковы. Например, можно попытаться вызвать метод sameAvg(), как показано в следующем фрагменте кода:
Integer inums[] = {1, 2, 3, 4, 5 };
Double dnums[] = {1.1, 2.2, 3.3, 4.4, 5.5 };
Stats iob = new Stats(inums);
Stats dob = new Stats(dnums);
if(iob.sameAvg(dob))
System.out.println("Averages are the same.");
else
System.out.println("Averages differ.");



Поскольку Stats — настраиваемый класс, его метод sameAvg() может обрабатывать любой объект типа Stats и кажется, что создать этот метод просто. К сожалению, возникнут проблемы, как только Вы попытаетесь объявить параметр типа для класса Stats. Класс Stats — это параметризованный тип и неясно, какой же тип объявлять для параметра типа класса Stats в списке параметров метода.
Вам может показаться, что решение выглядит так, как показано в следующих строках кода, использующих T как параметр типа.
// Этот пример не будет работать!
// Определяет, равны ли средние арифметические.
boolean sameAvg(Stats ob) {
if ((average) == ob.average())
return true;
return false;
}



К сожалению, приведенный пример будет обрабатывать только те объекты класса Stats, у которых тип такой же, как у объекта, вызвавшего метод. Например, если метод вызывает объект типа Stats, параметр ob должен тоже быть типа Stats. Такой метод нельзя использовать для сравнения среднего арифметического объекта Stats со средним арифметическим объекта типа Stats. Следовательно, предложенный подход не будет работать, за исключением нескольких ситуаций, и не даст общего (т. е. универсального) решения.
Для создания универсального метода sameAvg() Вы должны использовать другую функциональную возможность средств настройки типов — мета символьный аргумент, или символьную маску (wildcard argument). Метасимвольный аргумент задается знаком ? и представляет неизвестный тип. Используя такую маску, можно описать метод sameAvg( ) так, как показано в следующем фрагменте кода:

// Определяет, равны ли средние арифметические.
// Обратите внимание на применение метасимвола.
boolean sameAvg(Stats ob) {
if ((average) == ob.average())
return true;
return false;
}



В приведенном примере тип Stats соответствует любому объекту типа Stats и позволяет сравнивать средние арифметические двух объектов типа Stats, как показано в листинге 3.6.
Листинг 3.6. Применение метасимвола, или символьной маски
class Stats {
T[] nums;
// массив типа Number или его подкласса
// Передает конструктору ссылку на
// массив типа Number или его подкласса.
Stats(T[] o) {
nums = o;
}
// Всегда возвращает тип double.
double average() {
double sum = 0.0;

for(int i=0; i < nums.length; i++)
sum += nums[i].doubleValue();

return sum / nums.length;
}
// Определяет, равны ли два средних арифметических.
// Обратите внимание на использование метасимвола (или маски).
boolean sameAvg(Stats ob) {
if(average() == ob.average())
return true;

return false;
}
}
// Демонстрирует применение метасимвола.
class WildcardDemo {
public static void main(String args[]) {
Integer inums[] = { 1, 2, 3, 4, 5 };
Stats iob = new Stats(inums);
double v = iob.average();
System.out.println("iob average is " + v);

Double dnums[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
Stats dob = new Stats(dnums);
double w = dob.average();
System.out.println("dob average is " + w);

Float fnums[] = { 1.0F, 2.0F, 3.0F, 4.0F, 5.0F };
Stats fob = new Stats(fnums);
double x = fob.average();
System.out.println("fob average is " + x);

// Проверяет, у каких массивов одинаковые средние арифметические.
System.out.print("Averages of iob and dob ");
if(iob.sameAvg(dob))
System.out.println("are the same.");
else
System.out.println("differ.");

System.out.print("Averages of iob and dob ");
if(iob.sameAvg(fob))
System.out.println("are the same.");
else
System.out.println("differ.");
}
}




Далее приведен вывод программы из листинга 3.6:
iob average is 3.О
dob average is 3.3
fob average is 3.0
Averages of iob and dob differ.
Averages of iob and fob are the same.
Последнее замечание: важно понять, что метасимвол не влияет на тип создаваемого объекта класса Stats. Тип определяется ключевым словом extends в объявлении класса Stats. Метасимвол, или маска, обеспечивает совместимость любых допустимых объектов типа Stats.
Опубликовал Kest January 13 2009 00:44:57 · 0 Комментариев · 7353 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Нет комментариев.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Visual Basic Script
Preview
EMSQuickImport
Программа "AutoRu...
База данных фильм...
Delphi Быстрый Ст...
Правила программи...
IIIDTrans
MxProtector
Расширенный загру...
Info
DragMe [Исходник ...
C++ Builder в за...
Dreamsoft Progres...
32 урока по Delphi
Assembler. Учебни...
Моделирование дви...
Задача о 8ми ладьях
Создание Web-сайт...
SODA [Исходник на...

Топ загрузок
Приложение Клие... 100470
Delphi 7 Enterp... 87090
Converter AMR<-... 20078
GPSS World Stud... 12851
Borland C++Buil... 11846
Borland Delphi ... 8604
Turbo Pascal fo... 7039
Visual Studio 2... 4999
Калькулятор [Ис... 4803
FreeSMS v1.3.1 3542
Случайные статьи
Управление перемещ...
Кроме общедостутюг...
Сортировка массиво...
Рекурсивное вычисл...
Лайтбоксы и вывеск...
Поперечное сечение...
Сквозная запись
Конфигурирование м...
Реляционные отноше...
ДОСТОИНСТВА И НЕДО...
Пример организации...
Подмена функций ст...
Глава 1. СОМ как у...
Глава 4. Сбор данн...
Новый вид панели F...
присвоения чрезмер...
Мой окончательный ...
Туннельный режим I...
Другие «примочки»
Асимметричная пере...
Количество информа...
ПРЕДИСЛОВИЕ КО ВТО...
Сущность эффекта и...
Применяйте AsyBEUI...
Мультиметоды для к...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?