1. 结合上一讲泛型内容,这边继续补充它的知识点,如何继承泛型类别,实现泛型接口
带有泛型的父类
带有泛型的子类:package com.ahuier.jdk5; /** * 带有泛型的父类 * @author xukunhui * * @param <T1> * @param <T2> */ public class Parent<T1, T2> { private T1 foo1; private T2 foo2; public T1 getFoo1() { return foo1; } public void setFoo1(T1 foo1) { this.foo1 = foo1; } public T2 getFoo2() { return foo2; } public void setFoo2(T2 foo2) { this.foo2 = foo2; } }
package com.ahuier.jdk5; /** * 定义泛型的子类,继承带有泛型的父类Parent * 这个类中不单有getFoo3() 和 SetFoo3()两个方法,它同时还具备了父类Parent的里面的四个getter()或setter()方法 * 注意Parent中的两个属性是没法继承下来的,属性不继承 * @author xukunhui * */ public class Child<T1, T2, T3> extends Parent<T1, T2> { private T3 foo3; public T3 getFoo3() { return foo3; } public void setFoo3(T3 foo3) { this.foo3 = foo3; } }
2. 泛型不只是可以用在类上,还是用在接口上。带泛型的接口的实现
定义带泛型的接口
定义实现这个带泛型的接口的类package com.ahuier.jdk5; /** * 定义带泛型的接口 * @author xukunhui * * @param <T1> * @param <T2> */ public interface ParentInterface<T1, T2> { public void setFoo1(T1 foo1); public void setFoo2(T2 foo2); public T1 getFoo1(); public T2 getFoo2(); }
【小技巧】:在实现接口过程中,需要重写实现接口中的类,可以使用Eclipse自动生成工具:source --> Override/Implement Methods 选择需要实现的接口。package com.ahuier.jdk5; /** * 定义带泛型的实现类,实现接口ParentInterface * @author xukunhui * * @param <T1> * @param <T2> */ public class ChildClass<T1, T2> implements ParentInterface<T1, T2> { private T1 foo1; private T2 foo2; @Override public void setFoo1(T1 foo1) { this.foo1 = foo1; } @Override public void setFoo2(T2 foo2) { this.foo2 = foo2; } @Override public T1 getFoo1() { return this.foo1; } @Override public T2 getFoo2() { return this.foo2; } }
3. 泛型在实际开发中一般用在哪些地方? 集合中要用泛型,所以碰到集合最好写成泛型的格式。
4. 增强的for循环(For-Each循环): 简化了集合的遍历
語法如下
for(type element : array) {System.out.println(element)....
}
[说明:其中type表示数组中的元素的类型,element自定义的一个变量]
[说明]:从例子可以总结出增强的for循环再哪种场合下不宜使用呢?在如果要指定数组中的特定元素信息的时候不便使用(比如要对数组下标为7的元素进行操作的时候),因为其循环失去了索引的信息,所以这种情况下用增强的for循环难度要加大。package com.ahuier.jdk5; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; public class ForTest { public static void main(String[] args) { int[] arr = { 1, 2, 3, 4, 5 }; //旧的方式 for(int i = 0; i < arr.length; i++){ System.out.println(arr[i]); } System.out.println("------------------------"); //使用增强的for循环方式 for(int element : arr){ System.out.println(element); } System.out.println("------------------------"); String[] names = {"hello", "world", "welcome"}; for(String name : names){ System.out.println(name); } System.out.println("------------------------"); //使用增强的for循环遍历二维数组 int[][] arr2 = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; for(int[] row : arr2){ for(int element : row){ System.out.println(element); } } //使用增强的for循环定义在集合中 Collection<String> co1 = new ArrayList<String>(); //ArrayList实现了List接口,List接口又继承了Collection接口,相当于ArrayList实现了Colletion接口 co1.add("one"); co1.add("two"); co1.add("three"); for(String str : co1){ System.out.println(co1); } /* * 总结三种对于集合遍历方式 * 可以发现第三种增强的for循环方式是最少代码量的,也是最清晰的 */ List<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); //方式一:使用for循环遍历 for(int i = 0; i < list.size(); i++){ System.out.println(list.get(i)); } //方式二:使用迭代器的方式 for(Iterator<String> iter = list.iterator(); iter.hasNext();){ System.out.println(iter.next()); } //方式三:使用增强的for循环 for(String str : list){ System.out.println(str); } } }
【总结】:当遍历集合或数组时,如果需要访问集合或数组的下标,那么最好使用旧式的方式来实现循环或遍历,而不要使用增强的for循环,因为它丢失了下标信息。
5. 自动装箱/拆箱(Autoboxint/unboxing):大大方便了基本类型数据和它们包装类的使用。
自动装箱:基本类型自动转为包装类.(int >> Integer)
自动拆箱:包装类自动转为基本类型.(Integer >> int)
[注意:自动装箱/拆箱 是针对8个原生数据类型以及他们的包装类是使用的]
编译执行结果:package com.ahuier.jdk5; import java.util.ArrayList; import java.util.Collection; public class BoxTest { public static void main(String[] args) { int a = 3; //这种写法是错误的,8个原生数据类型是不能做为参数传递给泛型的。泛型传递的必须是一个类。 // Collection<int> c = new ArrayList<int>(); Collection<Integer> c = new ArrayList<Integer>(); c.add(new Integer(3)); //以前的方式是这样写的, //现在可以利用自动装箱. c.add(3); //将int 类型的3转换为Integer类型并放到集合中去 c.add(a + 3); for(Integer i : c){ System.out.println(i); } } }
3
3
6