黑马程序员——枚举学习笔记

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

第一讲  枚举


一:枚举概述

     什么是枚举?现实生活我们肯能会经常碰到,今天星期几?一个星期是固定的,就7天。再比如,一年有几个季节,这些固定的数在java中该如何表示呢?用常量1-7表示星期几?用常量1-4表示“春夏秋冬”?显然这不是好的方法。原因有如下几点:

1)类型不安全,如果用数字表示,则可实现算数运算,显然不合理

2)没有命名空间:比如,在使用Spring(春天时)必须加前缀Season,否则容易和其他类中常量混淆

3)打印输出不够合理,比如用1代表Spring时,打印输出的是1,显然不直观

     而java也从JDK1.5以后给我们提供了一个更好的方法来表示这些固定的常用的数——即:枚举,


二:手动实现枚举类

      如需手动实现枚举类,可按如下要求设计

     1) 通过Private将构造函数封装起来

     2) 把这个类所有要实现的字段用public static final 修饰起来

     3)   如果有必要则提供外界一些静态方法,可以按某种特定格式来获取与之匹配的实例

public class Season
{
	//把Season类定义成不可变的,将其属性也定义成final
	private final String name;
	private final String desc;
	public static final Season SPRING = new Season("春天" , "趁春踏青");
	public static final Season SUMMER = new Season("夏天" , "夏日炎炎");
	public static final Season FALL = new Season("秋天" , "秋高气爽");
	public static final Season WINTER = new Season("冬天" , "围炉赏雪");

	public static Season getSeaon(int seasonNum)
	{
		switch(seasonNum)
		{
			case 1 :
				return SPRING;
			case 2 :
				return SUMMER;
			case 3 :
				return FALL;
			case 4 :
				return WINTER;
			default :
				return null;
		}
	}

	//将构造器定义成private访问权限
	private Season(String name , String desc)
	{
		this.name = name;
		this.desc = desc;
	}
	//只为name和desc属性提供getter方法
	public String getName()
	{
		 return this.name;
	}
	public String getDesc()
	{
		 return this.desc;
	}
}

测试自己编写的枚举类:

<span style="white-space:pre">	</span><pre name="code" class="java">public class TestSeason
{
	public TestSeason(Season s)
	{
		System.out.println(s.getName() + ",这真是一个"+ s.getDesc() + "的季节");
	}
	public static void main(String[] args) 
	{
		//直接使用Season的FALL常量代表一个Season对象
		new TestSeason(Season.FALL);
	}
}

 

由此可见,利用枚举可以避免创建对象的随意性,使数据得到更好的封装!

三:JDK1.5以后的枚举

自己创建枚举对象比较麻烦,有没有更快捷的方式呢,Java从JDK1.5以后就给大家提供了枚举关键字:enum ,使大家可以更快速的创建枚举对象。

enum 和class interface 关键字等同。

使用enum 创建的枚举类和普通类相似,但也有区别,区别如下:

1)使用enum 创建的非抽象的枚举类默认使用final修饰,因此,枚举类不可有子类

2)使用enum定义的枚举类默认继承Java.Lang.Enum类

3)枚举类的构造器只能是Private,默认就是Private 

4)  枚举类的所有实例必须在第一行显示列出,默认会添加public static final 修饰符

枚举类一般都设计成不可变类! 为了安全。因此枚举类中的Field值都应该用private final 来修饰!为此,则在构造器中去初始化这些变量(因为在初始化代码块和定义Field时指定默认值一般在枚举类中都不会用到) 如下定义一个男,女枚举

public enum Gender 
{
	//此处的枚举值必须调用对应构造器来创建
	MALE("男"),FEMALE("女");
	private String name;
	//枚举类的构造器只能使用private修饰
	private Gender(String name)
	{
		this.name = name;
	}
	public String getName()
	{
		 return this.name;
	}
}

MALE("男") 其实就相当于:public static final Gender MALE =new Gender("男");

四:实现接口的枚举类

        枚举类和普通类一样,可以实现接口,实现接口的方法可以在枚举类里直接实现,如下:

public class EnumTest {


	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(Season.Spring);
		System.out.println(Season.Spring.Description());
		System.out.println(Season.Summer);
		System.out.println(Season.Summer.Description());
	}
    
	public interface IDes
	{
		String Description();//描述
	}
	
	enum  Season implements IDes
	{
		Spring("春天"),
		Summer("夏天");
		
		
		@Override
		public String Description() {
			
			return "这是一个季节";
		}
		private final String name;
		private Season(String name)
		{
			this.name=name;
		}
		public String getName()
		{
			return this.name;
		}
		
	}

输出如下:

Spring
这是一个季节
Summer
这是一个季节

由此可见,如果实现接口的方法在枚举类里实现,那么每个枚举值调用此方法时,显示的结果一样,显然在大多数情况下,这不是我们想要的结果,我们想要每个枚举值调用方法时显示不同的结果,那怎么办?我们学过匿名内部类,同样,在枚举中也可以利用匿名内部类来完成我们想要的结果,如下:

public class EnumTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(Season.Spring);
		System.out.println(Season.Spring.Description());
		System.out.println(Season.Summer);
		System.out.println(Season.Summer.Description());
	}
    
	public interface IDes
	{
		String Description();//描述
	}
	
	enum  Season implements IDes
	{
		Spring("春天")
		{
			@Override
			public String Description() 
			{				
				return "这是一个春暖花开的季节";
			}
		},
		Summer("夏天")
		{
			public String Description() 
			{
				
				return "这是一个炎热的季节";
			}
		};
		
				
		private final String name;
		private Season(String name)
		{
			this.name=name;
		}
		public String getName()
		{
			return this.name;
		}
		
	}
}
结果如下:

Spring
这是一个春暖花开的季节
Summer
这是一个炎热的季节


注意:此时枚举类的修饰符是abstract ,此时的枚举类相当于一个抽象枚举类。只有当定义一个非抽象枚举类时,修饰符才会是:final  !!!


五:包含抽象方法的枚举类

上题也可不用接口,而在枚举类里定义一个抽象方法,有各个枚举值的匿名内部类去实现,代码如下:

public class EnumTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(Season.Spring);
		System.out.println(Season.Spring.Description());
		System.out.println(Season.Summer);
		System.out.println(Season.Summer.Description());
	}
    

	enum  Season 
	{
		Spring("春天")
		{
			@Override
			public String Description() 
			{				
				return "这是一个春暖花开的季节";
			}
		},
		Summer("夏天")
		{
			public String Description() 
			{
				
				return "这是一个炎热的季节";
			}
		};
		
				
		public abstract String Description();//定义一个抽象方法,如果不加这句,直接在内部类里写方法,则编译通不过,说明:枚举类必须提供枚举值使用方法的规范
		private final String name;
		private Season(String name)
		{
			this.name=name;
		}
		public String getName()
		{
			return this.name;
		}
		
	}
}
结果如下:

Spring
这是一个春暖花开的季节
Summer
这是一个炎热的季节

枚举类中包含抽象方法时,枚举类不能显示指定abstract  修饰符,系统会自动添加!





















 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值