java(枚举、泛型).doc_第1页
java(枚举、泛型).doc_第2页
java(枚举、泛型).doc_第3页
java(枚举、泛型).doc_第4页
java(枚举、泛型).doc_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java程序设计课堂笔记第4章 枚举和泛型 -6.1 枚举 -6.2 泛型 1 知识点1.1 上次内容1. Java异常处理1.2 习题讲解1. 求int型数组元素的平均值。(提示:存在空对象异常和除数为0等潜在错误,要求使用异常进行处理。(参考教材128页)package cn.xit.java;public class avgDemo private staticint a =new int ;private static int sum = 0;private static double avg;public static void main(String args) for (int i : a) sum += i;try avg = sum / a.length; catch (Exception e) e.printStackTrace();System.out.println(avg);1.3 本次内容知识点1. 枚举2. 泛型了解1. 枚举扩展【重点】 1. 泛型2. 枚举难点1. 泛型2. 枚举2 具体内容6.1 枚举在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的。例如:星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素组成了四季的“数据集”。在java中如何更好的使用这些“数据集”呢?因此枚举便派上了用场。6.1.1 枚举简介 在JDK 1.5之前,JAVA可以有两种方式定义新类型:类和接口。对于大部分面向对象编程来说,这两种方法看起来似乎足够了。 但是在一些特殊情况下,这些方法就不适合。例如,想定义一个Color类,它只能有 Red、Green、Blue三种值,其他的任何值都是非法的,那么JDK 1.5之前虽然可以构造这样的代码,但是要做很多的工作,也有可能带来各种不安全的问题。而JDK 1.5之后引入的枚举类型(Enum)就能避免这些问题。 枚举就是规定好了指定的取值范围,所有的内容只能从指定的范围中取得,也就是一个类只能产生固定的几个对象。范例:使用定义类实现枚举操作。class Color public static final Color RED = new Color(红色);/ 定义第一个对象public static final Color GREEN = new Color(绿色); / 定义第二个对象public static final Color BLUE = new Color(蓝色);/ 定义第三个对象private String name;private Color(String name) / 构造方法私有化,同时设置颜色的名称this.setName(name); / 为颜色的名字赋值public String getName() / 取得颜色名称return ;public void setName(String name) / 设置颜色名称 = name;public static Color getInstance(int i) / 得到一个颜色,只能从固定的几个颜色中取得switch (i) case 1: / 返回红色对象return RED;case 2: / 返回绿色对象return GREEN;case 3: / 返回蓝色对象return BLUE;default: return null;/ 错误的值范例:使用接口表示一组范围package cn.xit.java;public interface Colorpublic static final int RED = 1 ;/ 表示红色public static final int GREEN = 2 ;/ 表示绿色public static final int BLUE = 3 ;/ 表示兰色public class ColorDemo02 public static void main(String args) System.out.println(Color.RED + Color.GREEN) ;/ 颜色相加6.1.2 定义一个枚举类型 在JDK 1.5之后,引入了一个新的关键字类型 enum,可以直接定义枚举类型,格式如下:public enum 枚举类型名称枚举对象1,枚举对象2,枚举对象n ;范例:定义一个Color的枚举类型。package cn.xit.java;public enum Color / 定义枚举类型RED, GREEN, BLUE;/ 定义枚举的三个类型范例:枚举操作。public class GetEnumContent public static void main(String args) Color c = Color.BLUE ;/ 取出蓝色System.out.println(c) ;/ 输出信息/*使用foreach输出枚举内容*/for(Color c:Color.values()/ 枚举.values()表示得到全部枚举的内容System.out.println(c) ;/ 输出枚举内容/*使用switch进行判断*/public static void print(Color color)switch(color)/ 判断每个颜色case RED:/ 直接判断枚举内容System.out.println(红颜色) ;break ;case GREEN:/ 直接判断枚举内容System.out.println(绿颜色) ;break ;case BLUE:/ 直接判断枚举内容System.out.println(蓝颜色) ;break ;default:/ 未知内容System.out.println(未知颜色) ;break ;6.1.3 Enum使用enum关键字可以定义一个枚举。实际上此关键字表示的是java.lang.Enum类型,即:使用enum声明的枚举类型,就相当于定义一个类,而此类默认继承java.lang.Enum类。java.lang.Enum类的定义如下: public abstract class EnumE extends Enumextends Objectimplements Comparable, java.io.Serializable枚举类的主要操作方法:No.方法类型描述1protected Enum(String name,int ordinal)构造接收枚举的名称和枚举的常量创建枚举对象2protected final Object clone()throws CloneNotSupportedException普通克隆枚举对象3public final int compareTo(E o)普通对象比较4public final boolean equals(Object other)普通比较两个枚举对象5public final int hashCode()普通返回枚举常量的哈希码6public final String name()普通返回此枚举的名称7public final int ordinal()普通返回枚举常量的序数8public static T extends Enum T valueOf(Class enumType,String name)普通返回带指定名称的指定枚举类型的枚举常量protectedEnum(String name, int ordinal)6.1.4 取得枚举的信息枚举类的构造方法:protected Enum(String name,int ordinal);在枚举类建立完成之后,实际上都会为其调用枚举类中的构造方法,为其赋值,在Enum类的构造方法中的第一个参数name就是定义的枚举的名称,第二个参数ordinal则会从0开始依次进行编号。之后可以使用Enum类中提供的name()和ordinal()方法取得名字和编号。 范例:获取枚举的信息(编号和名称)package cn.xit.java;enum Color RED, GREEN, BLUE;public class HelloDemo public static void main(String args) for (Color c : Color.values() System.out.println(c.ordinal() + - + ();6.1.5为枚举类的每一个对象赋值可以通过构造方法和setter方法两种方式为枚举中的每个属性赋值: 每个枚举类中都有其指定好的若干对象,当然,每一个枚举对象中也可以包含多个属性。而这些属性也可以通过构造方法为其赋值。 也可以通过调用setter()的方式为指定的属性赋值,但是必须明确每一个枚举类的对象。如果操作的对象是RED,则名字应该为“红色”,如果操作的对象是GREEN,则名字应该为“绿色”等。 范例:通过构造方法为属性赋值package cn.xit.java;enum Color RED(红色), GREEN(绿色), BLUE(兰色);/ 定义枚举的三个类型private Color(String name)/ 定义构造方法this.setName(name) ;/ 设置名字private String name ;/ 定义name属性public String getName() / 取得name属性return name;public void setName(String name) / 设置name属性 = name;public class HelloDemo public static void main(String args) for(Color c:Color.values()/ 枚举.values()表示得到全部枚举的内容System.out.println(c.ordinal() + - + () + ( + c.getName() + ) ;/ 输出范例:通过setter方法为属性赋值。package cn.xit.java;enum Color RED, GREEN, BLUE;/ 定义枚举的三个类型private String name ;/ 定义name属性public String getName() return name;public void setName(String name) switch(this)case RED:/ 判断是否是红色if(红色.equals(name) = name ;/ 设置名称elseSystem.out.println(设置内容错误。) ;break ;case GREEN:/ 判断是否是红色if(绿色.equals(name) = name ;/ 设置名称elseSystem.out.println(设置内容错误。) ;break ;case BLUE:/ 判断是否是红色if(蓝色.equals(name) = name ;/ 设置名称elseSystem.out.println(设置内容错误。) ;break ;public class HelloDemo public static void main(String args) Color c = Color.BLUE;c.setName(蓝色);System.out.println(c.ordinal() + - + () + ( + c.getName() + ) ;/ 输出6.1.6 valueof()如果不想通过“枚举类.对象”的形式取得每一个枚举类的对象,也可以使用Enum类定义的“枚举类.valueof()”方法的形式进行调用。 范例:通过valueof()方法取得枚举对象。package cn.xit.java;enum Color RED, GREEN, BLUE;/ 定义枚举的三个类型private String name ;/ 定义name属性public String getName() return name;public void setName(String name) switch(this)case RED:/ 判断是否是红色if(红色.equals(name) = name ;/ 设置名称elseSystem.out.println(设置内容错误。) ;break ;case GREEN:/ 判断是否是绿色if(绿色.equals(name) = name ;/ 设置名称elseSystem.out.println(设置内容错误。) ;break ;case BLUE:/ 判断是否是蓝色if(蓝色.equals(name) = name ;/ 设置名称elseSystem.out.println(设置内容错误。) ;break ;public class HelloDemo public static void main(String args) /Color c = Color.BLUE;Color c = Enum.valueOf(Color.class, BLUE) ;/c.setName(兰色) ;/ 设置一个错误的名字c.setName(蓝色) ;/ 设置一个正确的名字System.out.println(c.ordinal()+-+()+(+c.getName()+);6.1.7 综合示例范例:枚举综合示例。package cn.xit.java;/* * 枚举用法详解*/public class HelloDemo /* * 1、普通枚举 */ public enum ColorEnum red, green, yellow, blue; /* * 2、枚举像普通的类一样可以添加属性和方法,可为它添加静态和非静态的属性或方法 */ public enum SeasonEnum /注:枚举写在最前面,否则编译出错 spring, summer, autumn, winter; private final static String position = test; public static SeasonEnum getSeason() if (test.equals(position) return spring; else return winter; /* * 3、实现带有构造器的枚举 */ public enum Gender /通过括号赋值,而且必须带有一个参构造器和一个属性跟方法,否则编译出错 /赋值必须都赋值或都不赋值,不能一部分赋值一部分不赋值;如果不赋值则不能写构造器,赋值编译也出错 MAN(MAN), WOMEN(WOMEN); private final String value; /构造器默认也只能是private, 从而保证构造函数只能在内部使用 Gender(String value) this.value = value; public String getValue() return value; /* * 订单状态 * 4、实现带有抽象方法的枚举 */ public enum OrderState /* 已取消 */ CANCEL public String getName()return 已取消;, /* 待审核 */ WAITCONFIRM public String getName()return 待审核;, /* 等待付款 */ WAITPAYMENT public String getName()return 等待付款;, /* 正在配货 */ ADMEASUREPRODUCT public String getName()return 正在配货;, /* 等待发货 */ WAITDELIVER public String getName()return 等待发货;, /* 已发货 */ DELIVERED public String getName()return 已发货;, /* 已收货 */ RECEIVED public String getName()return 已收货; public abstract String getName(); public static void main(String args) /枚举是一种类型,用于定义变量,以限制变量的赋值;赋值时通过“枚举名.值”取得枚举中的值 ColorEnum colorEnum = ColorEnum.blue; switch (colorEnum) case red: System.out.println(color is red); break; case green: System.out.println(color is green); break; case yellow: System.out.println(color is yellow); break; case blue: System.out.println(color is blue); break; /遍历枚举 System.out.println(遍历ColorEnum枚举中的值); for(ColorEnum color : ColorEnum.values() System.out.println(color); /获取枚举的个数 System.out.println(ColorEnum枚举中的值有+ColorEnum.values().length+个); /获取枚举的索引位置,默认从0开始 System.out.println(ColorEnum.red.ordinal();/0 System.out.println(ColorEnum.green.ordinal();/1 System.out.println(ColorEnum.yellow.ordinal();/2 System.out.println(ColorEnum.blue.ordinal();/3 /枚举默认实现了java.lang.Comparable接口 System.out.println(ColorEpareTo(ColorEnum.green);/-1 /- System.out.println(=); System.err.println(季节为 + SeasonEnum.getSeason(); /- System.out.println(=); for(Gender gender : Gender.values() System.out.println(gender.value); /- System.out.println(=); for(OrderState order : OrderState.values() System.out.println(order.getName(); 6.2 泛型6.2.1为什么要有泛型现在要求设计一个可以表示出坐标点的类,坐标由X和Y组成,坐标的表示方法有以下三种: 整数表示:x = 10、y = 20 小数表示:x = 10.5、y = 20.6 字符串表示:x = 东经180度、y = 北纬210度 问:此类该如何设计? 【分析】看到这样的要求,首先就要考虑到必须建立好一个表示坐标点的类 Point,此类中有两个属性分别用来表示x坐标和y坐标,但是x和y中所保存的数据类型会有三种(int、float、String),而要想使用一个类型可以同时接收这样的三种类型数据,则现在只能使用Object,因为Object类可以接收任何类型的数据,都会自动发生向上转型操作,这样三种数据类型将按以下的方式进行转换: 数字(int) 自动装箱成Integer 向上转型使用Object接收 小数(float) 自动装箱成Float 向上转型使用Object接收 字符串(String) 向上转型使用Object接收 范例代码:设计Point类,并使用该类。package cn.xit.java;class Point private Object x;/ 表示x坐标private Object y;/ 表示y坐标public void setX(Object x) this.x = x;public void setY(Object y) this.y = y;public Object getX() return this.x;public Object getY() return this.y;public class HelloDemo public static void main(String args) Point p = new Point() ;p.setX(10) ;/ 利用自动装箱操作:int - Integer - Objectp.setY(北纬210度) ;/ String - Objectint x = (Integer)p.getX() ;/ 取出数据int y = (Integer)p.getY() ;/ 取出数据此处出现了类转换错误/*Exception in thread main java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integerat cn.xit.java.HelloDemo.main(HelloDemo.java:24)*/System.out.println(整数表示,X坐标为: + x) ;System.out.println(整数表示,Y坐标为: + y) ;发现在String想Integer进行转换时出现了错误。数据无法完成转换。6.2.2 使用泛型泛型可以解决数据类型的安全性问题,它主要的原理是在类声明的时候通过一个标识(T)表示类中某个属性的类型或者是某个方法的返回值及参数类型。这样在类声明或实例化的时候只要指定好需要的类型即可。 泛型类定义格式:访问权限 class 类名称访问权限 泛型类型标识 变量名称 ;访问权限 泛型类型标识 方法名称() ;访问权限 返回值类型声明 方法名称(泛型类型标识 变量名称) ;泛型对象定义:类名称 对象名称 = new 类名称() ;范例:使用泛型声明Point类。package cn.xit.java;class Point / 此处可以是任意的标识符号,T是type的简称private T x;/ 此变量的类型由外部决定private T y;/ 此变量的类型由外部决定public T getX() / 返回值的类型由外部指定return x;public void setX(T x) / 设置的类型由外部指定this.x = x;public T getY() / 返回值的类型由外部指定return y;public void setY(T y) / 设置的类型由外部指定this.y = y;public class HelloDemo public static void main(String args) Point p = new Point() ;p.setX(10) ; / 利用自动装箱操作:int - Integerp.setY(20) ; int x = (Integer)p.getX() ;/ 取出数据int y = (Integer)p.getY() ;/ 取出数据System.out.println(整数表示,X坐标为: + x) ;System.out.println(整数表示,Y坐标为: + y) ;泛型使用注意事项: 在泛型的指定中,是无法指定基本数据类型的,必须设置成一个类,这样在设置一个数字的时候就必须使用包装类,而在JDK 1.5之后提供了自动装箱的操作,操作时也不会太复杂。 构造方法可以为类中的属性初始化,那么如果类中的属性通过泛型指定,而又需要通过构造设置属性内容的时候,构造方法的定义与之前并无不同,不需要像声明类那样指定泛型。 使用格式:访问权限 构造方法 ( 参数名称) 在泛型应用中最好在声明类的时候指定好其内部的数据类型,例如:“Info”,但也可以不指定类型,这样一来用户在使用这样的类时,就会出现不安全的警告信息。 6.2.3 指定多个泛型类型如果一个类中有多个属性需要使用不同的泛型声明,则可以在声明类的时候指定多个泛型类型。 范例:指定多个泛型类型。package cn.xit.java;class Notepad / 此处指定两个泛型类型private K key;/ 此变量的类型由外部决定private V value;/ 此变量的类型由外部决定public K getKey() return key;public void setKey(K key) this.key = key;public V getValue() return value;public void setValue(V value) this.value = value;6.2.4 匹配任意类型的通配符:?泛型类定义好之后,被使用时都设置了一个固定的数据类型,如:Point p = new Point() ;而泛型操作中也可以通过通配符(?)接收任意指定泛型类型的对象。在程序开发中,引用传递是最经常见到的,在泛型类的引用传递操作中,泛型类型必须匹配才可以传递,否则是无法传递的。范例:泛型类对象引用传递的问题。package cn.xit.java;class Point / 此处指定两个泛型类型private T x;/ 此变量的类型由外部决定private T y;/ 此变量的类型由外部决定public T getX() return x;public void setX(T x) this.x = x;public T getY() return y;public void setY(T y) this.y = y;public class HelloDemopublic static void main(String args)Point p=new Point();p.setX(10);p.setY(20);fun(p); /编译出错,无法传递public static void fun(Point point)System.out.println(内容:+point);以上程序中,尽管Integer类是Object类的子类,但是在进行引用传递时同样无法进行操作。此时,如果想让程序正确执行,可以将fun()方法中定义的Point修改为Point,即不指定泛型。package cn.xit.java;class Point / 此处指定两个泛型类型private T x;/ 此变量的类型由外部决定private T y;/ 此变量的类型由外部决定public T getX() return x;public void setX(T x) this.x = x;public T getY() return y;public void setY(T y) this.y = y;public class HelloDemopublic static void main(String args)Point p=new Point();p.setX(10);p.setY(20);fun(p); /编译正确,可以传递public static void fun(Point point)System.out.println(内容:+point);但是这样做并没有在Point中指定任何的泛型类型,有些不妥。因此,为了解决这个问题,Java中引入了通配符“?”,该通配符表示可以接收此类型的任意泛型对象。代码修改如下:package cn.xit.java;class Point / 此处指定两个泛型类型private T x;/ 此变量的类型由外部决定private T y;/ 此变量的类型由外部决定public T getX() return x;public void setX(T x) this.x = x;public T getY() return y;public void setY(T y) this.y = y;public class HelloDemopublic static void main(String args)Point p=new Point();p.setX(10);p.setY(20);fun(p); /编译出错,无法传递public static void fun(Point point)System.out.println(内容:+point);Point这样就显得比较合理了,但是此时需要注意的是,该类型不能设置被泛型指定的内容,只作为引用传递是传递泛型对象。如:public class HelloDemopublic static void main(String args)Point p=new Point();p.setX(10); /无法设置内容p.setY(20); /无法设置内容6.2.5 受限泛型在引用传递中,泛型操作中也可以设置一个泛型对象的范围上限和范围下限。范围上限使用extends关键字声明,表示参数化的类型可能是所指定的类型,或者是此类型的子类,而范围下限使用super进行声明,表示参数化的类型可能是所指定的类型,或者是此类型的父类型,直至Object类。 设置上限: 声明对象:类名称 对象名称 定义类:访问权限 类名称 设置下限: 声明对象:类名称 对象名称 定义类:访问权限 类名称范例:泛型的上限。package cn.xit.java;class Point / 此处指定两个泛型类型private T x;/ 此变量的类型由外部决定public T getX() return x;public void setX(T x) this.x = x;public class HelloDemo public static void main(String args) Point p1 = new Point() ;/ 声明Integer的泛型对象Point p2 = new Point() ;/ 声明Integer的泛型对象p1.setX(30) ;/ 设置整数,自动装箱p2.setX(30.1f)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论