美文网首页
泛型边界

泛型边界

作者: 呆呆李宇杰 | 来源:发表于2017-09-15 22:36 被阅读152次

边界

边界的功能是可以用于泛型参数上设置限制条件,尽管这使得你可以强制规定泛型可以应用的类型,但是其潜在的一个更重要的效果是可以按照自己的边界类型来调用方法。
因为擦除移除了类型信息,所以,可以用无界泛型参数调用的方法只能是那些可以用Object调用的方法。但是,如果能够将这个参数限制为某种类型的子集,那么就可以用这些类型子集来调用方法。
而为了执行这种限制,Java泛型重用了extends关键字。这有一点很重要,即要理解extends关键字在泛型边界上下文的情况和在普通情况所具有的意义是完全不同的。
下面的代码展示了边界的基本要素。

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 ColloredDimension<T extends HasColor & Dimension> {
//}

class ColoredDimension<T extends Dimension & HasColor> {
    T item;

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

// As with inheritance, you can have only one
// concrete class but multiple interfaces
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 {

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

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


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

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

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

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 {

    @Override
    public void hearSubtleNoises() {

    }

    @Override
    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);

        // You can do this
        List<? extends SuperHearing> audioBoys;

        // But you can't do this
        // List<? extends SuperHearing & SuperSmell> dogBoys;
    }
}

通配符将被限制为单一边界。

相关文章

  • Scala 中的特殊符号 ---- 泛型边界 <: >:

    泛型的边界 <: 和 >: 符号 <:和>:都是用来表示泛型的边界,如:有以下类声明: 声明拥有泛型的类: 说明:...

  • 泛型不能使用具有继承关系的类型

    使用通配符?可以,但是会使的泛型的类型检查失去意义给泛型加上边界? extend E 给泛型加上上边界

  • 008-自定义泛型,Collections

    自定义泛型 泛型类 代码实现 测试 泛型接口 代码实现 泛型方法 代码演示 测试 泛型上下边界 Collectio...

  • 泛型边界

    extends 和 super关键字运用在泛型中,主要作用是限制泛型的边界,确定在泛型方法或者泛型类中可是利用泛型...

  • 泛型边界

    边界 边界的功能是可以用于泛型参数上设置限制条件,尽管这使得你可以强制规定泛型可以应用的类型,但是其潜在的一个更重...

  • Java-泛型

    - 1.泛型定义 - 2.泛型使用 - 3.泛型上下边界 - 4.JVM如何实现的泛型?   1、定义 Jdk1....

  • Java-Java泛型(Generic)

    一.定义泛型 1.泛型类(作用范围是整个类) 2.泛型方法(作用范围是整个方法) 二.泛型边界 简书: http:...

  • Java泛型—Java语法糖,只在编译有作用,编译后擦出泛型

    Java泛型—Java语法糖,只在编译有作用,编译后擦出泛型 在代码进入和离开的边界处,会处理泛型 Java泛型作...

  • 最强整理:一线互联网移动架构师筑基必备技能之Java篇

    移动架构师筑基必备技能 一、深入Java泛型 泛型的作用与定义通配符与嵌套泛型上下边界RxJava中泛型的使用分析...

  • Java泛型

    1. 泛型通配符与PECS 为什么要使用泛型通配符和边界 List泛型转换需要用到通配符 ? “装A的List” ...

网友评论

      本文标题:泛型边界

      本文链接:https://www.haomeiwen.com/subject/bswesxtx.html