学习java或者软件开发的出去编程有时候项目经理经常会问到有关泛型的理解;
泛型:是指在定义类或者接口的时候可以为类和接口指定类型形参,在定义变量、定义方法是该类型形参可以当做普通的类型来使用,并且该类型形参在定义变量和创建对象的确定
1、定义泛型类,程序实例代码如下:
[java] view plaincopy
01.<span style="font-size:18px">public class GenericClass<E> {
02. /**
03. * @param args
04. * 自定义泛型类
05. */
06. private E e;//变量
07.
08. public GenericClass(){
09.
10. }
11. public GenericClass(E e){
12. this.e=e;
13. }
14. public E getE(){//返回值类型
15. return e;
16. }
17. public void println(E e){//函数参数
18. System.out.println(e);
19. }
20. public static void main(String[] args) {
21. GenericClass<Integer> gc=new GenericClass<Integer>();
22. gc.println(1111111);
23.
24. GenericClass<String> gc1=new GenericClass<String>();
25. gc1.println("string");
26.
27. }
28.}</span>
2、实现泛型接口,在实现泛型接口或者类的时候,可以不指定类型形参,但是编译的时候会出现警告;
[java] view plaincopy
01.public interface InterfaceGeneric<E> {
02. public E getE();
03. public void save(E e);
04.}
[java] view plaincopy
01.public class InterfaceImplement implements InterfaceGeneric<Integer>{
02. /**
03. * @param args
04. */
05. @Override
06. public Integer getE() {
07. // TODO Auto-generated method stub
08. return null;
09. }
10. @Override
11. public void save(Integer e) {
12. // TODO Auto-generated method stub
13.
14. }
15. public static void main(String[] args) {
16. // TODO Auto-generated method stub
17.
18. }
19.}
3、类型通配符
在定义一个方法的时候,如果该方法的参数为集合形参,集合的元素类型是不确定的,那我们该怎么定义呢?
假如如下所示的定义:
[java] view plaincopy
01.<span style="font-size:18px">// public void println(List<Object> list){//函数参数
02.// int count=list.size();
03.// for(int i=0;i<count;i++){
04.// System.out.println(list.get(i));
05.// }
06.// }</span>
[java] view plaincopy
01.<span style="font-size:18px"> List<String> list=new ArrayList<String>();
02. list.add("a");
03. //println(list);不正确,因为List<String>不是List<Object>的子类</span>
那么这样的使用方法是不正确的,因为函数的形参是List<Object>类型的,而实参是List<String>类型的,但是需要注意的一点是List<String>并不是List<Object>的子类,所以这样写是不正确的,那么在这个list里的元素类型不确定的情况下怎么定义这个函数呢,这就用到了类型通配符;在java中类型通配符是一个?;类型通配符是所有泛型List的父类,在定义函数的时候用?代替类型,就可以在以后使用的时候定义各种各样的类型的List集合,如下的程序实例所示:
[java] view plaincopy
01.<span style="font-size:18px"> public void println(List<?> list){//函数参数List使用类型通配符
02. int count=list.size();
03. for(int i=0;i<count;i++){
04. System.out.println(list.get(i));
05. }
06. }</span>
[java] view plaincopy
01.<span style="font-size:18px">
02. List<String> list=new ArrayList<String>();
03. list.add("a");
04. gc.println(list);</span>
4、类型通配符上限
定义一个形状类,有一个画图的方法,可以画各种各样的形状,则可以定义为接口如下所示:
[java] view plaincopy
01.<span style="font-size:18px">public interface Shape {
02. public void draw();
03.}</span>
定义一个圆类和矩形类,分别实现上面定义的接口,然后重写方法draw();
[java] view plaincopy
01.<span style="font-size:18px">public class Rectangle implements Shape {
02.
03. @Override
04. public void draw() {
05. // TODO Auto-generated method stub
06. System.out.println("draw a rectangle");
07. }
08.
09.}
10.public class Circle implements Shape {
11.
12. @Override
13. public void draw() {
14. // TODO Auto-generated method stub
15. System.out.println("draw a circle");
16. }
17.
18.}
19.
20.</span>
假如有一个画布可以画很多图形,则可以这样定义该画布类:
[java] view plaincopy
01.<span style="font-size:18px">public class Canves {
02. /**
03. * @param args
04. */
05.//这里使用List<Shape>不正确,会出现编译错误,因为List<Circle> List<Rectangle>不是List<Shape>的子类
06.// public void draw(List<Shape> shapeList){
07.//
08.// }
09.
10. /*
11. *可以考虑使用类型通配符的方式List<?>
12. *但是这里使用的类型通配符是配的所有的类型,所以加进去的元素就是Object类型的
13. *这里需要强制类型转换,降低了程序的执行效率;所以可以使用java提供的类型通配符的上限定义方法
14. **/
15.// public void draw(List<?> shapeList){
16.// for(Object obj:shapeList){
17.// Shape shape=(Shape)obj;
18.// shape.draw();
19.// }
20.// }
21. /*
22. *这里使用类型通配符的上限的形式定义list集合的元素类型List<? extends Shape>
23. * */
24. public void draw(List<? extends Shape> shapeList){
25. for(Shape shape:shapeList){
26. shape.draw();
27. }
28. }
29.
30. public static void main(String[] args) {
31. Canves c=new Canves();
32. List<Circle> listCircle=new ArrayList<Circle>();
33. listCircle.add(new Circle());
34.
35. List<Rectangle> listRectangle=new ArrayList<Rectangle>();
36. listRectangle.add(new Rectangle());
37.
38. c.draw(listCircle);// 1
39. c.draw(listRectangle);// 2
40. }
41.}
42.</span>
draw()方法的参数里list集合的类型使用的是类型通配符的上限形式,这样既可以往list集合中添加不同的Shape类子类的对象,而且不用进行强制类型转换。
5、泛型方法
泛型方法的使用效果和类型通配符非常相似
[java] view plaincopy
01.<span style="font-size:18px">public class GenericMethod {
02. //泛型方法
03. public <E> void genericmethod(List<E> a){
04.
05. for(E t:a)
06. System.out.println(t.toString());
07.
08. }
09.
10. public static void main(String[] param){
11. List<String> list=new ArrayList<String>();
12. list.add("dfd");
13. list.add("dfd");
14. list.add("dfd");
15. list.add("dfd");
16. new GenericMethod().genericmethod(list);
17.
18. List<Integer> list1=new ArrayList<Integer>();
19. list1.add(1);
20. list1.add(2);
21. list1.add(3);
22. list1.add(4);
23. new GenericMethod().genericmethod(list1);
24. }
25.}</span>
|
|