泛型(8):边界

        本章前面简单地介绍过边界。边界使得你可以在用于泛型的参数类型上设置限制条件。尽管这使得你可以强制规定泛型可以应用的类型,但是其潜在的一个更重要的效果是你可以按照自己的边界类型来调用方法。

        因为擦除移除了类型信息,所以,可以用无界泛型参数调用的方法只是那些可以用Object调用的方法。但是,如果能够将这个参数限制为某个类型子集,那么你就可以用这些类型子集来调用方法。为了执行这种限制,java泛型重用了extends关键字。对你来说有一点很重要,即要理解extends关键字在泛型边界上下文环境中和在普通情况下所具有的意义是完全不同的。下面的示例展示了边界的基本要素:

import java.awt.Color;

interface HasColor {
	Color getColor();
}

class Colored<T extends HasColor> {
	T item;

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

	T getItem() {
		return item;
	}

	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;
	}

	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 {

	@Override
	public int weight() {
		return 0;
	}

	@Override
	public Color getColor() {
		return null;
	}

}

public class BasicBounds {
	public static void main(String[] args) {
		Solid<Bounded> solid = new Solid<>(new Bounded());
		solid.color();
		solid.getY();
		solid.weight();
	}
}

        你可能已经观察到了,BasicBounds.java看上去包含可以通过继承消除的冗余。下面,可以看到如何在继承的每个层次上添加边界限制:

import java.awt.Color;

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);
	}

	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<>(new Bounded());
		solid2.color();
		solid2.getY();
		solid2.weight();
	}
}

        HoldItem直接持有一个对象,因此这种行为被继承到了Colored2中,它也要求其参数与HasColor一致。ColoredDimension2和Solid2进一步扩展了这个层次结构,并在每个层次上都添加了边界。现在这些方法被继承,因而不必在每个类中重复。下面是具有更多层次的示例:

import java.util.List;

/**
 * 超级能力
 */
interface SuperPower {
}

/**
 * 射线视觉
 */
interface XRayVision extends SuperPower {
	void seeThroughWalls();
}

/**
 * 超级听力
 */
interface SuperHearing extends SuperPower {
	void hearSubtleBoises();
}

/**
 * 超级嗅觉
 */
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.hearSubtleBoises();
	}

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

class SuperHearSmell implements SuperHearing, SuperSmell {

	@Override
	public void trackBySmell() {
	}

	@Override
	public void hearSubtleBoises() {
	}
}

class DogBoy extends CanineHero<SuperHearSmell> {

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

public class EpicBattle {
	static <POWER extends SuperHearing> void useSuperHearing(SuperHero<POWER> hero) {
		hero.getPower().hearSubtleBoises();
	}

	static <POWER extends SuperHearing & SuperSmell> void superFind(SuperHero<POWER> hero) {
		hero.getPower().hearSubtleBoises();
		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> audioBoys;
	}
}

    注意,通配符被限制为单一边界。

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ywz大柳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值