Навигация
Главная
Поиск
Форум
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
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Модуль Forms 65535
ТЕХНОЛОГИИ ДОСТ... 63028
Имитационное мо... 58346
Реклама
Сейчас на сайте
Гостей: 7
На сайте нет зарегистрированных пользователей

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

Моделирование процесса поступления заявок в систему, состоящую из трёх Э...
Моделирование автомойки на GPSS + Отчет + Блок схемы
Информационная система - транспортный парк на Turbo Pascal (База данных)...

Реклама



Подписывайся на 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 Комментариев · 7388 Прочтений · Для печати

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


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



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

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

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

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

Пароль



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

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

Случайные загрузки
C# в кратком изло...
PHP 5
Меню проводника в...
Панель статистики...
AlignEdit
Разработка клиент...
Cтатьи Королевств...
Cooltray
Xrumer 4 Platinum...
C++ : библиотека ...
Calendar
CLR via C#
DCMintry
Animated Menus
Моделирование дви...
Андрей Боровский....
Самоучитель PHP 4
Assistant
SMLPack v1.0
DateEdit

Топ загрузок
Приложение Клие... 100480
Delphi 7 Enterp... 87866
Converter AMR<-... 20082
GPSS World Stud... 13503
Borland C++Buil... 12057
Borland Delphi ... 8671
Turbo Pascal fo... 7048
Visual Studio 2... 5005
Калькулятор [Ис... 4908
FreeSMS v1.3.1 3545
Случайные статьи
Пошаговое выполнен...
Термоядерный синтез
ИНФОРМАЦИОННАЯ БЕЗ...
Схема типичной инф...
Переход в графичес...
Наслаждайтесь рабо...
Возможности окруже...
КЛАСС ИЛИ ЗАПИСЬ?
6.1. Пример
Процедура FREEMEM....
Здесь мы рассмотри...
Синтаксис регулярн...
Операторы прерыван...
Программирование а...
Поиск заданного э...
Ищите возможности ...
Подсистема STREAMS
6.8. Равенство
write(X)
Управление вызовом...
Как нажать кнопку ...
Презентации Prezi
Материнская плата
Спам-фильтр
Процедура Ellipse ...
Статистика



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


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