русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Ограничения


Дата добавления: 2015-06-12; просмотров: 518; Нарушение авторских прав


Ограничения, уже упоминавшиеся ранее в этой главе, сужают круг параметров типов, используемых при параметризации. Хотя это позволяет предъявлять требования к типам, к которым применяется ваш параметризованный код, у ог­раничений имеется и другой, потенциально более важный эффект: возможность вызова методов, определенных в ограничивающих типах. Поскольку стирание уничтожает информацию о типе, при отсутствии ограничений для параметров типов могут вызываться только методы Object. Но, если ограничить параметр подмножеством типов, вы сможете вызвать методы из этого подмножества. Для установления ограничений в Java используется ключевое слово extends. Важно понимать, что в контексте параметризации extends имеет совершенно иной смысл, нежели в обычной ситуации. Следующий пример демонстрирует основы установления ограничений:

//: generics/BasicBounds.java

 

interface HasColor { java.awt.Color getColor(); }

 

class Colored<T extends HasColor> {

T item;

Colored(T item) { this.item = item; }

T getItem() { return item; }

// Ограничение позволяет вызвать метод:

java.awt.Color color() { return item.getColor(); }

}

 

class Dimension { public int x, y, z; }

 

// Не работает -- сначала класс, потом интерфейсы:

// class ColoredDimension<T extends HasColor & Dimension> {

 

// Несколько ограничений-

class ColoredDimension<T extends Dimension & HasColor> {

T item;

ColoredDimension(T item) { this.item = item; }

T getItem() { return item; }

java.awt.Color color() { return item.getColor(); }

int getX() { return item.x; }

int getY() { return item.y; }

int getZ() { return item.z; }

}

 

interface Weight { int weight(); }

 

// Как и при наследовании, конкретный класс может быть только один,



// а интерфейсов может быть несколько:

class Solid<T extends Dimension & HasColor & Weight> {

T item;

Solid(T item) { this.item = item; }

T getItem() { return item; }

java.awt.Color color() { return item.getColor(); }

int getX() { return item.x; }

int getY() { return item.y; }

int getZ() { return item.z; }

int weight() { return item.weight(); }

}

 

class Bounded

extends Dimension implements HasColor, Weight {

public java.awt.Color getColor() { return null; }

public int weight() { return 0; }

}

 

public class BasicBounds {

public static void main(String[] args) {

Solid<Bounded> solid =

new Solid<Bounded>(new Bounded());

solid.color();

solid.getY();

solid.weight();

}

}

Вероятно, вы заметили, что пример BasicBounds.java содержат некоторую избыточность, которая может быть устранена посредством наследования. С каждым уровнем наследования добавляются новые ограничения:

//: generics/InheritBounds.java

class HoldItem<T> {

T item;

HoldItem(T item) { this.item = item; }

T getItem() { return item; }

}

 

class Colored2<T extends HasColor> extends HoldItem<T> {

Colored2(T item) { super(item); }

java.awt.Color color() { return item.getColor(); }

}

 

class ColoredDimension2<T extends Dimension & HasColor>

extends Colored2<T> {

ColoredDimension2(T item) { super(item); }

int getX() { return item.x; }

int getY() { return item.y; }

int getZ() { return item.z; }

}

 

class Solid2<T extends Dimension & HasColor & Weight>

extends ColoredDimension2<T> {

Solid2(T item) { super(item); }

int weight() { return item.weight(); }

}

 

public class InheritBounds {

public static void main(String[] args) {

Solid2<Bounded> solid2 =

new Solid2<Bounded>(new Bounded());

solid2.color();

solid2.getY();

solid2.weight();

}

}

HoldItem просто хранит объект; это поведение наследуется классом Colored2, который также требует, чтобы его параметр реализовывал HasColor. ColoredDimension2 и Solid2 продолжают расширение иерархии и добавляют на каждом уровне новые ограничения. Теперь методы наследуются, и их не нужно повторять в каждом классе. Пример с большим количеством уровней:

//: generics/EpicBattle.java

// Demonstrating bounds in Java generics.

import java.util.*;

 

interface SuperPower {}

interface XRayVision extends SuperPower {

void seeThroughWalls();

}

interface SuperHearing extends SuperPower {

void hearSubtleNoises();

}

interface SuperSmell extends SuperPower {

void trackBySmell();

}

 

class SuperHero<POWER extends SuperPower> {

POWER power;

SuperHero(POWER power) { this.power = power; }

POWER getPower() { return power; }

}

 

class SuperSleuth<POWER extends XRayVision>

extends SuperHero<POWER> {

SuperSleuth(POWER power) { super(power); }

void see() { power.seeThroughWalls(); }

}

 

class CanineHero<POWER extends SuperHearing & SuperSmell>

extends SuperHero<POWER> {

CanineHero(POWER power) { super(power); }

void hear() { power.hearSubtleNoises(); }

void smell() { power.trackBySmell(); }

}

 

class SuperHearSmell implements SuperHearing, SuperSmell {

public void hearSubtleNoises() {}

public void trackBySmell() {}

}

 

class DogBoy extends CanineHero<SuperHearSmell> {

DogBoy() { super(new SuperHearSmell()); }

}

 

public class EpicBattle {

// Ограничения в параметризованных методах:

static <POWER extends SuperHearing>

void useSuperHearing(SuperHero<POWER> hero) {

hero.getPower().hearSubtleNoises();

}

static <POWER extends SuperHearing & SuperSmell>

void superFind(SuperHero<POWER> hero) {

hero.getPower().hearSubtleNoises();

hero.getPower().trackBySmell();

}

public static void main(String[] args) {

DogBoy dogBoy = new DogBoy();

useSuperHearing(dogBoy);

superFind(dogBoy);

// Так можно:

List<? extends SuperHearing> audioBoys;

// А так нельзя:

// List<? extends SuperHearing & SuperSmell> dogBoys;

}

}



<== предыдущая лекция | следующая лекция ==>
Массивы параметризованных типов | Метасимволы


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.01 сек.