java泛型中的extends和super

泛型

泛型也是一种多态,只不过是编译时的多态。首先举一个简单的例子说明一下java泛型的语法:

class Base<T>{
     private T t;
     public void set(T t){
	this.t=t;
	System.out.println(t.getClass().getName());
     }
}
public class Test {
  public static void main(String[] args){
      Base<Integer> b1=new Base<Integer>();
      b1.set(new Integer(0));
      Base<Double> b2=new Base<Double>();
      b2.set(new Double(0));
 }
}

运行结果:

java.lang.Integer
java.lang.Double

java泛型区别C++泛型的一个明显特点就是不用template声明了,需要的时候直接在类名、接口名后或函数名前加<T>即可。

还有一点不一样,类型参数所支持的默认操作:

  • java泛型类型参数所定义的变量不支持基本的运算操作:

  • C++是可以的
template<class T>
T add(const T& t1,const T& t2){
      return t1+t2;
}
int _tmain(int argc, _TCHAR* argv[])
{
     cout<<add(4,5)<<endl;
     system("pause");
     return 0;
}

 WildCards:通配符

在java泛型中,List<String>并不是List<Object>的子类(否则的话,List<String>容器中就可以加入非String类型的元素了),所以在一些抽象编程/面向接口编程(如函数参数传递以及返回值上)就会出现一些问题。

void printCollection(Collection<Object> c) {
    for (Object e : c) {
        System.out.println(e);
    }
}

虽然Object是所有类型的父类型,但Collection<Object>并不是所有容器的父容器,所以printCollection并不能接受诸如Collection<String>的参数。在这个问题上通配符就派上用场了。

void printCollection(Collection<?> c) {
    for (Object e : c) {
        System.out.println(e);
    }
}

 Collection<?>就可以用来表示所有容器的父容器了。

受限通配符:extends & super

extends的应用:

public abstract class Shape {
    public abstract void draw(Canvas c);
}

public class Circle extends Shape {
    private int x, y, radius;
    public void draw(Canvas c) {
        ...
    }
}

public class Rectangle extends Shape {
    private int x, y, width, height;
    public void draw(Canvas c) {
        ...
    }
}
public class Canvas {
    public void draw(Shape s) {
        s.draw(this);
   }
public void drawAll(List<? extends Shape> shapes) {
	for(Shape s: shapes){
             s.draw(this);
	}
   }
}

super的应用:

interface Sink<T> {
    flush(T t);
}
public static <T> T writeAll(Collection<T> coll, Sink<? super T> snk) {
    T last;
    for (T t : coll) {
        last = t;
        snk.flush(last);
    }
    return last;
}
...
Sink<Object> s;
Collection<String> cs;
String str = writeAll(cs, s);

如果是(Collection<? extends T>, Sink<T>),则的T的类型为Object,writeAll的返回类型为Ojbect而不是String。

还有两个经典应用:

<T extends Comparable<?super T>>
TreeSet(Comparator<? super E> c)

总结:

extends是上界限定符,如果传递的类型参数为某一类的子类或某个接口的实现,extends更适用,一般应用于类型多态时的参数传递或容器中的元素读取。

super是下界限定符,如果传递的类型参数为该类或该类的父类或该类实现的接口,super更适用,比如存在多种类型参数,需要将其限定为最具体的类型时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值