java 泛型-自限定类型

一,什么是自限定类型

1,普通泛型
/**
 * @ClassName BasicHolder
 * @Description 普通泛型类
 * @Author liangfeng
 * @Date 2019-06-26 11:01
 * @Version 1.0
 **/
public class BasicHolder<T> {
    private T element;

    public void set(T t){
        element = t;
    }

    public T get(){
        return element;
    }

    public void f(){
        System.out.println(element.getClass().getName());
    }
}

/**
 * @ClassName BaseOther
 * @Description TODO
 * @Author liangfeng
 * @Date 2019-06-26 11:05
 * @Version 1.0
 **/
public class BaseOther extends BasicHolder<Other> {
}


/**
 * @ClassName Other
 * @Description TODO
 * @Author liangfeng
 * @Date 2019-06-26 11:04
 * @Version 1.0
 **/
public class Other {
}

/**
 * @ClassName Test
 * @Description TODO
 * @Author liangfeng
 * @Date 2019-06-26 11:05
 * @Version 1.0
 **/
public class Test {

    public static void main(String[] args) {
        BaseOther baseOther1 = new BaseOther();
        baseOther1.set(new Other()); //传入其他类型
        Other other = baseOther1.get();//得到其他类型
        baseOther1.f();
    }
}

普通泛型就不必详细解释啦 。

2,自限定泛型

自限定的泛型 格式如下

<T extends SelfBounded<T>>

它所对应的实际类型如下实例

public class A extends SelfBounded<A> {
}

解释:一个类继承一个带有泛型的父类 父类泛型类型为该类的类型,也就是说基类用其导出类作为泛型的类型,基类中所使用的泛型类型都是该导出类
意义:先看如下代码

/**
 * @ClassName SelfBounded
 * @Description 自限定泛型类
 * @Author liangfeng
 * @Date 2019-06-26 11:16
 * @Version 1.0
 **/
public class SelfBounded<T extends SelfBounded<T>> {

    private T element;

    public SelfBounded<T> setElement(T t){
        element = t;
        return this;
    }

    public T getElement(){
        return element;
    }

    public void f(){
        System.out.println(element.getClass().getName());
    }

}

/**
 * @ClassName A
 * @Description TODO
 * @Author liangfeng
 * @Date 2019-06-26 11:25
 * @Version 1.0
 **/
public class A extends SelfBounded<A> {
}

public static void main(String[] args) {
        A a = new A();
        a.setElement(new A());//参数传递A类型
        A element = a.getElement();//返回的也是A类型
		
}

和前面的普通泛型比较你发现有什么区别吗 ?
看方法传递的参数:
普通类型方法参数和返回是使用其他类型
自限定类型的方法参数和放回值类型只能是它自己的类型,可以保证类型参数和正在被定义的类相同

二,参数协变

自限定的价值在于他可以产生参数协变
参数协变:方法参数类型随着子类类型变化而变化
先观察下面两部分代码
1,普通泛型参数协变

/**
 * @ClassName Base
 * @Description TODO
 * @Author liangfeng
 * @Date 2019-06-26 17:16
 * @Version 1.0
 **/
public class Base {
}


/**
 * @ClassName BaseSon
 * @Description TODO
 * @Author liangfeng
 * @Date 2019-06-26 17:17
 * @Version 1.0
 **/
public class BaseSon extends Base {
}

/**
 * @ClassName GenericSetter
 * @Description TODO
 * @Author liangfeng
 * @Date 2019-06-26 17:18
 * @Version 1.0
 **/
public class GenericSetter<T> {

    public void set(T t){
        System.out.println("GenericSetter.set(base)");
    }
}

/**
 * @ClassName GenericSetterSon
 * @Description TODO
 * @Author liangfeng
 * @Date 2019-06-26 17:23
 * @Version 1.0
 **/
public class GenericSetterSon extends GenericSetter<Base> {

    public void set(BaseSon baseSon){
        System.out.println("GenericSetterSon.set(baseson)");
    }
}



    public static void main(String[] args) {
        Base base = new Base();
        BaseSon baseSon = new BaseSon();
        GenericSetterSon genericSetterSon = new GenericSetterSon();
        genericSetterSon.set(baseSon);
        genericSetterSon.set(base);
    }


以上的输出结果

GenericSetterSon.set(baseson)
GenericSetter.set(base)

2,自限定的协变参数

/**
 * @ClassName SelfBoundSetter
 * @Description TODO
 * @Author liangfeng
 * @Date 2019-06-26 17:28
 * @Version 1.0
 **/
public class SelfBoundSetter<T extends SelfBoundSetter<T>> {

    void set(T t){
        System.out.println("SelfBoundSetter.set"+t.getClass().getName());
    }
}

/**
 * @ClassName SelfBoundSetterSon
 * @Description TODO
 * @Author liangfeng
 * @Date 2019-06-26 17:30
 * @Version 1.0
 **/
public class SelfBoundSetterSon extends SelfBoundSetter<SelfBoundSetterSon> {
	//子类无需实现新方法
}


    public static void main(String[] args) {
        SelfBoundSetterSon selfBoundSetterSon = new SelfBoundSetterSon();
        SelfBoundSetterSon selfBoundSetterSon1 = new SelfBoundSetterSon();
        SelfBoundSetter selfBoundSetter = new SelfBoundSetter();
        selfBoundSetterSon.set(selfBoundSetterSon1);
        //selfBoundSetterSon.set(selfBoundSetter);报错 不能将SelfBoundSetter类型传递给selfBoundSetterSon类型的参数
    }

输出结果

SelfBoundSetter.settest.zixianding.SelfBoundSetterSon

对比:
第一部分代码 输出结果可以看出 子类方法和父类方法实现啦重载而不是覆盖 覆盖的话将不会输出GenericSetter.set(base)
第二部分代码可以看出当子类继承父类的时候父类中的函数参数类型变成子类的类型而且只有一个方法没有重载而且子类的方法不能接受父类类型参数
也就是说不使用自限定泛型继承机制会介入实现重载有父类和子类的两个方法
使用自限定类型只有子类中的一个方法不存在父类的方法。

参考:《java编程思想(第四版)》第十五章 15.12小节

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值