泛型类
疯狂java讲义中,给出了下面这个例子来描述泛型类
//定义Apple时使用了泛型声明
public class Apple<T> {
//使用T定义实例变量
private T info;
public Apple(){}
public Apple(T info) {
this.info = info;
}
public T getInfo() {
return info;
}
public void setInfo(T info) {
this.info = info;
}
public static void main(String[] args) {
//由于传给T形参的是String,所以构造器参数只能是String
Apple<String> a1 = new Apple<>("苹果");
System.out.println(a1.getInfo());
//由于传给T形参的是Double,所以构造器参数只能是Double或double
Apple<Double> a2 = new Apple<>(5.23);
System.out.println(a2.getInfo());
}
}
泛型,简单来讲就是规定类型,在集合中用的比较多,但我们也可以用泛型定义类或者接口甚至方法
泛型类,可以看成是有类型的类
这个类型(泛型形参)可以是自定义的,可以是String,可以是Integer,但是不能是int,double等基本数据类型,有时候,自定义的类型甚至可能是无意义的
这个泛型形参,可以被赋值,就像代码中的 Apple<String> a1 = new Apple<>("苹果");
和Apple<Double> a2 = new Apple<>(5.23);
T就像是我们的int a
中的a,但是实际使用的时候,需要赋值,像例子中赋值的String和Double(不能是double)
还有一个,书上的原话
当创建带泛型声明的自定义类,为该类定义构造器时,构造器名还是原来的类名,不要增加泛型声明。例如为
Apple<T>
类定义构造器,其构造器名依然是Apple,而不是Apple<T>
,但调用该构造器时却可以使用Apple<T>
的形式,当然应该为T形参传入实示的类型参數。
这个的话看一下原来的示例代码就明白了
public Apple(T info) {//构造器,没有<>
this.info = info;
}
Apple<String> a1 = new Apple<>("苹果");//调用的时候可以使用<>
泛型类派生子类
带有泛型声明的接口或者类,创建子类的时候,不能再包含类型形参,而是具体的类型 例如
public class A extends Apple<T>()//错误
public class A extends Apple<String>()//正确
书上说,使用方法时必须把形参给赋值,使用类时倒是不用 但是,可能是我JDK版本(13)比较高的缘故,或者IDEA优化了,使用方法时也可以不用,但是类型就是object的类型了, 或者我理解有误,还请大佬指出
public class A extends Apple{
public static void main(String[] args) {
A aa = new A();
aa.setInfo("hhh");
System.out.println(aa.getInfo());
}
}
输出hhh
public class A extends Apple{
public static void main(String[] args) {
A aa = new A();
aa.setInfo("hhh");
aa.setInfo(4);
System.out.println(aa.getInfo());
}
}
输出4
参考:
疯狂java讲义第五版