泛型
泛型也是一种多态,只不过是编译时的多态。首先举一个简单的例子说明一下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更适用,比如存在多种类型参数,需要将其限定为最具体的类型时。