《Java程序设计-4-范型和枚举.ppt》由会员分享,可在线阅读,更多相关《Java程序设计-4-范型和枚举.ppt(21页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、JavaJava程序设计程序设计第四章第四章 范型和枚举范型和枚举4.4 4.4 范型范型 范型的一个作用:范型的一个作用:u如果我们需要安全的保证一个处理器其处理的对象如果我们需要安全的保证一个处理器其处理的对象只能是指定类型的对象,那么范型就可以发挥作用。只能是指定类型的对象,那么范型就可以发挥作用。一个范型的例子一个范型的例子uSet myObjSet=new Set myObjSet=new HashSet();HashSet();4.4.1 4.4.1 什么是范型?什么是范型?范型也被称为参数化类型范型也被称为参数化类型(parameterized type)(parameteriz
2、ed type),就是在定义类和接口时,规定了创建该类对象,就是在定义类和接口时,规定了创建该类对象时需要的一个或多个类型参数(注意:并非构造时需要的一个或多个类型参数(注意:并非构造函数的参数)。函数的参数)。uclass HashMap class HashMap u .u Value put(Key k,Value v).Value put(Key k,Value v).u Value get(Key k).Value get(Key k).u 其类型名用其类型名用keykey和和valuevalue临时表示就容易理解了,临时表示就容易理解了,其真正的类型只有到运行时才能完全确定。其真正
3、的类型只有到运行时才能完全确定。一个不用范型的例子一个不用范型的例子import java.util.*;import java.util.*;public class OldStyle public class OldStyle upublic static void main(String args)public static void main(String args)uHashSet myObjSet=new HashSet();/HashSet myObjSet=new HashSet();/创建一个集合,存放对象创建一个集合,存放对象umyObjSet.add(new Intege
4、r(0);/myObjSet.add(new Integer(0);/向集合中增加一个整型对象向集合中增加一个整型对象umyObjSet.add(new Integer(1);/myObjSet.add(new Integer(1);/umyObjSet.add(new Double(2);/myObjSet.add(new Double(2);/向集合中增加一个实型对象向集合中增加一个实型对象uObject x=null;Object x=null;ufor(Iterator it=myObjSet.iterator();it.hasNext();)for(Iterator it=myObj
5、Set.iterator();it.hasNext();)ux=it.next();/x=it.next();/获得下一个对象获得下一个对象uif(x instanceof Integer)/if(x instanceof Integer)/如果如果x x是整型类型是整型类型u System.out.printf(“%d”,(Integer)x);/System.out.printf(“%d”,(Integer)x);/强制转换的对象类强制转换的对象类型为整型型为整型uelse if(x instanceof Double)/else if(x instanceof Double)/如果如果x
6、 x是实型类型是实型类型u System.out.printf(“%f”,(Double)x);/System.out.printf(“%f”,(Double)x);/强制转换对象类型为强制转换对象类型为实型实型u u u 一个应用范型的程序一个应用范型的程序import java.util.HashSet;import java.util.HashSet;import java.util.Iterator;import java.util.Iterator;public class NewStyle public class NewStyle upublic static void main
7、(String args)public static void main(String args)u/创建一个集合,存放整型对象创建一个集合,存放整型对象uHashSet myObjSet=new HashSet();HashSet myObjSet=new HashSet();umyObjSet.add(new Integer(0);/myObjSet.add(new Integer(0);/向集合中增加一个整型向集合中增加一个整型对象对象umyObjSet.add(new Integer(1);/myObjSet.add(new Integer(1);/umyObjSet.add(new
8、Integer(2);/myObjSet.add(new Integer(2);/ufor(Integer x:myObjSet)for(Integer x:myObjSet)uSystem.out.println(x);System.out.println(x);u u 两个程序的差异两个程序的差异创建集合对象的方法变了,由原来的创建集合对象的方法变了,由原来的uHashSet myObjSet=new HashSet()HashSet myObjSet=new HashSet()uHashSet myObjSet=new HashSetHashSet myObjSet=new HashSe
9、t()()。u这是一个重要的变化,它声明集合只容纳整型对象。这是一个重要的变化,它声明集合只容纳整型对象。访问集合的方法得到了简化,可以放心的直接使用访问集合的方法得到了简化,可以放心的直接使用从集合中获得的每个对象。从集合中获得的每个对象。当然,限制了集合中包含的元素类型。对于特殊情当然,限制了集合中包含的元素类型。对于特殊情况下希望集合中存放某几种特别类型的对象(如具况下希望集合中存放某几种特别类型的对象(如具有派生关系)时可能会有不便,这个问题可以用特有派生关系)时可能会有不便,这个问题可以用特殊的范型定义来解决。殊的范型定义来解决。4.4.2 4.4.2 范型声明范型声明1 1 类型变
10、量类型变量 u通过前面的程序我们已经看到,通过将一个集合通过前面的程序我们已经看到,通过将一个集合在声明时事先指定容纳的类型,如:在声明时事先指定容纳的类型,如:uHashSet myObjSet=new HashSet myObjSet=new HashSet();HashSet();4.4.2 4.4.2 范型声明范型声明(cont.)(cont.)2 2 范型类的定义范型类的定义uReadingRoom.javaReadingRoom.java示例程序示例程序。如何使用如何使用ReadingRoomReadingRoom类?类?uReadingRoomReadingRoom bookRo
11、om=bookRoom=new ReadingRoom new ReadingRoom();();4.4.2 4.4.2 范型声明范型声明(cont.)(cont.)在范型定义中,也可以限制在范型定义中,也可以限制T T这种未知类型的这种未知类型的范围,如范围,如ReadingRoomReadingRoom,这,这里限制了里限制了T T的父类是的父类是MediaMedia。这里需要注意以下。这里需要注意以下几点:几点:u类的类型参数声明紧跟在类名之后,其个数可类的类型参数声明紧跟在类名之后,其个数可以有多个,如以有多个,如ReadingRoomReadingRoom。u类声明时的类型参数在对象
12、内可以直接被作为类声明时的类型参数在对象内可以直接被作为一种类型来使用,参见下面的多态方法。一种类型来使用,参见下面的多态方法。u类型参数在创建该类的实例时,需要用明确的类型参数在创建该类的实例时,需要用明确的类型来代替。类型来代替。4.4.2 4.4.2 范型声明范型声明(cont.)(cont.)3 3 多态方法多态方法 u范型范型JavaJava编程用语中,用类型进行参数化的方法被编程用语中,用类型进行参数化的方法被称为多态方法(称为多态方法(Polymorphic methodPolymorphic method)。)。上面的上面的程序在以下几个地方都用到了范型的定义。程序在以下几个地
13、方都用到了范型的定义。upublic void add(T t)public void add(T t)方法声明中的参数类型方法声明中的参数类型upublic T getFirst()public T getFirst()方法返回值类型方法返回值类型多态方法多态方法 的示例的示例public class MathUtils public class MathUtils upublic static T1 extends Number,T2 extends public static Number max(T1 x,T2 y)Number Number max(T1 x,T2 y)u retur
14、n x.doubleValue()y.doubleValue()?x:y;return x.doubleValue()y.doubleValue()?x:y;u upublic static void main(String args)public static void main(String args)u Number t;Number t;u t=MathUtils.t=MathUtils.maxmax(10.1f,9.1d);(10.1f,9.1d);u System.System.outout.println(t);.println(t);u 何处声明类型参数何处声明类型参数类声明时
15、定义,如果该范型类型需要在类和对象内类声明时定义,如果该范型类型需要在类和对象内部使用,就要在类的声明时附加类的参数信息,如部使用,就要在类的声明时附加类的参数信息,如同同ReadingRoomReadingRoom声明的那样:声明的那样:upublic class ReadingRoompublic class ReadingRoomu这里的这里的T T作为类型参数在整个类内部都可以作为一作为类型参数在整个类内部都可以作为一个未知类型被引用。个未知类型被引用。方法声明时定义,如果仅在一个方法内使用,就可方法声明时定义,如果仅在一个方法内使用,就可以在方法声明时添加此参数类型声明,如同下面语以
16、在方法声明时添加此参数类型声明,如同下面语句:句:upublic static T max(T x,public static T max(T x,T y)T y)public class ReadingRoom List mediaList;/只能接受类型为只能接受类型为T的对象到列表集合的对象到列表集合public ReadingRoom()/构造函数构造函数this.mediaList=new ArrayList();/这里的这里的T和上面的参数和上面的参数T也一致也一致public void add(T t)/将一个类型为将一个类型为T的对象增加到列表集合的对象增加到列表集合this.
17、mediaList.add(t);public T getFirst()T retuval=null;/定义了返回值,其类型为定义了返回值,其类型为TIterator it=this.mediaList.iterator();/获得了列表的迭代器获得了列表的迭代器if(it.hasNext()/hasNext()逻辑值,如果还有对象,返回逻辑值,如果还有对象,返回true retuval=it.next();/迭代器下移,获得对象,对象类型为迭代器下移,获得对象,对象类型为Treturn retuval;/返回值返回值4.4.3 4.4.3 类型参数通配符类型参数通配符 n在一些情况下,我们可
18、能并不关心未定的参数类型是什在一些情况下,我们可能并不关心未定的参数类型是什么,例如,对一个包含了数值元素的集合进行汇总运算,么,例如,对一个包含了数值元素的集合进行汇总运算,这种情况下,我们并不关心集合中的每一个对象是什么这种情况下,我们并不关心集合中的每一个对象是什么类型,只要它是数值型即可,而且,我们也希望集合中类型,只要它是数值型即可,而且,我们也希望集合中可以同时存放不同类型的数值类型,如整型、实型等,可以同时存放不同类型的数值类型,如整型、实型等,那又该如何做呢那又该如何做呢?答案就是采用参数通配符?答案就是采用参数通配符“?”“?”来解来解决这个问题。决这个问题。upublic
19、double sumList(List public double sumList(List values)values)n一个程序例子:一个程序例子:TestWildcard.javaTestWildcard.javapublic class TestWildcard/方法的参数是用范型类型声明的。public double sumList(List list)double total=0.0;for(Number o:list)total+=o.doubleValue();return total;public static void main(String args)List sampl
20、e=new ArrayList();sample.add(new Integer(1);/向集合增加一整型对象sample.add(new Double(2);/向集合增加一双精度对象sample.add(new Float(3);/向集合增加一单精度对象TestWildcard test=new TestWildcard();System.out.println(test.sumList(sample);4.5 4.5 枚举类枚举类如果我们想定义一个成绩类,成绩的范围只能如果我们想定义一个成绩类,成绩的范围只能是是A A、B B、C C、D D、E E,接受其它类型的值都是违,接受其它类型的
21、值都是违法的,应该如何定义呢?我们可以定义一个成法的,应该如何定义呢?我们可以定义一个成绩类,但如何表示成绩呢,整型、字符型?似绩类,但如何表示成绩呢,整型、字符型?似乎都不合适,因为没有明确的类型对应,即使乎都不合适,因为没有明确的类型对应,即使是字符型,那么超出了是字符型,那么超出了AA、B B、C C、D D、EE范围范围的字符程序需要特别处理,以便保证应用安全。的字符程序需要特别处理,以便保证应用安全。JavaJava语言提供了一种称为枚举的类型定义方法语言提供了一种称为枚举的类型定义方法.1 1 声明枚举类声明枚举类 upublic enum Grade A,public enum
22、Grade A,u B,B,u C,C,u D,D,u E;E;它包括一个关键字它包括一个关键字enumenum,一个新枚举类型的名字,一个新枚举类型的名字 GradeGrade以及为以及为GradeGrade定义的一组值,这里的值既非定义的一组值,这里的值既非整型,亦非字符型。整型,亦非字符型。枚举类是一个类,它的隐含父类是枚举类是一个类,它的隐含父类是java.lang.Enumjava.lang.Enum。枚举值并不是整数或其它类型,是被声明的枚举枚举值并不是整数或其它类型,是被声明的枚举类的自身实例,例如类的自身实例,例如A A是是GradeGrade的一个实例。的一个实例。枚举类不能
23、有枚举类不能有publicpublic修饰的构造函数,构造函数修饰的构造函数,构造函数都是隐含都是隐含privateprivate,编译器自动处理。,编译器自动处理。每个枚举值隐含都是由每个枚举值隐含都是由publicpublic、staticstatic、finalfinal修修饰的,无须自己添加这些修饰符。饰的,无须自己添加这些修饰符。枚举值可以用枚举值可以用=或或 equals()equals()进行彼此相进行彼此相等比较。等比较。一个枚举的例子一个枚举的例子n第一个类文件第一个类文件Grade.javaGrade.javanpublic enum Grade public enum G
24、rade n A,A,n B,B,n C,C,n D,D,n E En n第二个类文件第二个类文件AcademicRecord.javaAcademicRecord.javan第三个类文件第三个类文件Student.java Student.java 3 3 使用使用switchswitch判断判断uswitch(student.getGrade()switch(student.getGrade()u case A:case A:u u break;break;u case B:case B:u u break;break;u case C:case C:u u break;break;u c
25、ase D:case D:u u break;break;u case E:case E:u u break;break;u 4.4.为枚举类增加构造函数为枚举类增加构造函数enum Size enum Size uSmall(0.8),/SmallSmall(0.8),/Small的类型为的类型为Size,Size,而而SizeSize有指定的有指定的构造函数构造函数 uMedium(1.0),Medium(1.0),uLarge(1.2);/Large(1.2);/分号表示枚举值定义结束分号表示枚举值定义结束uprivate double pricingFactor;private double pricingFactor;u/构造函数构造函数,如如Small(0.8),pricingFactor=0.8Small(0.8),pricingFactor=0.8uSize(double p)Size(double p)upricingFactor=p;pricingFactor=p;u upublic double getPricingFactor()public double getPricingFactor()ureturn pricingFactor;return pricingFactor;u