java高新技术【3】(枚举总结)

【1】枚举
· 一:为什么要有枚举
    (1)问题:定义星期几或性别的变量,该这么定义?
    假设用1-7分别表示星期一到星期日,但有人可能会写成int weekday =0;
   

   (2)  枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。枚举可以让编译器在编译时.就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。


二 : 用普通类如何实现枚举功能,定义一个Weekday的类来模拟枚举功能。


     -私有的构造方法
     -每个元素分别用一个公有的静态成员变量表示
     -可以有若干公有方法或抽象方法 
  例如,要提供nextDay方法必须是抽象的。

 采用抽象方法定义nextDay就将大量的if.else语句转移成了一个个独立的类。


(1)这个类所定义出来的值 不是基本类型的  而是 对象类型,也只能是这里规定的那么几个值。不然会报错。





【2】java5的枚举

(1)枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。

(2)枚举元素必须位于枚举体重的最开始的部分,枚举元素列表的后要有分号与其他成员分隔。

把枚举中的成员方法和变量等放在枚举元素的前面,编译器报告错误。

【1】带构造方法的枚举


-构造方法必须定义成私有的
-如果有多个构造方法,该如何选择哪个构造方法?
 
-枚举元素MON和MON()的效果一样,都是调用默认构造方法。
 
         【2】实现带有构造方法的枚举
(1)元素列表必须位于枚举中所有内容的之前,也就是元素列表必须在最前面
(2)构造方法必须是私有的private
(3)在枚举元素的后面加上()指定构造时候要调用的构造方法



  【3】带方法的枚举
-定义枚举TrafficLamp
-实现普通的next方法
-实现抽象的next方法:每个元素分别是由枚举类的子类来生产的实例对象,
这些子类采用类似内部类的方式进行定义。

-增加上表示时间的构造方法
红灯过后就是绿灯,绿灯过后是黄灯,黄灯过后是红灯
·枚举只有一个成员时,就可以作为一种单例的实现方式。


【3】Enum


Enum作为Sun全新引进的一个关键字,看起来很象是特殊的class, 它也可以有自己的变量,
可以定义自己的方法,可以实现一个或者多个接口。 
当我们在声明一个enum类型时,我们应该注意到enum类型有如下的一些特征。 

  1.它不能有public的构造函数,这样做可以保证客户代码没有办法新建一个enum的实例。 


  2.所有枚举值都是public , static , final的。
注意这一点只是针对于枚举值,我们可以和在普通类里面定义 变量一样定义其它任何类型的非枚举变量,
这些变量可以用任何你想用的修饰符。 


  3.Enum默认实现了java.lang.Comparable接口。 

  4.Enum覆载了了toString方法,因此我们如果调用Color.Blue.toString()默认返回字符串”Blue”. 

  5.Enum提供了一个valueOf方法,这个方法和toString方法是相对应的。
调用valueOf(“Blue”)将返回Color.Blue.
因此我们在自己重写toString方法的时候就要注意到这一点,
一把来说应该相对应地重写valueOf方法。 

  6.Enum还提供了values方法,这个方法使你能够方便的遍历所有的枚举值。 

  7.Enum还有一个oridinal的方法.这个方法返回枚举值在枚举类种的顺序,

这个顺序根据枚举值声明的顺序而定,这里Color.Red.ordinal()返回0。 


方法摘要
protected  Objectclone()
          抛出 CloneNotSupportedException。
 intcompareTo(E o)
          比较此枚举与指定对象的顺序。
 booleanequals(Object other)
          当指定对象等于此枚举常量时,返回 true。
protected  voidfinalize()
          枚举类不能有 finalize 方法。
 Class<E>getDeclaringClass()
          返回与此枚举常量的枚举类型相对应的 Class 对象。
 inthashCode()
          返回枚举常量的哈希码。
 Stringname()
          返回此枚举常量的名称,在其枚举声明中对其进行声明。
 intordinal()
          返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。
 StringtoString()
          返回枚举常量的名称,它包含在声明中。
static
<T extends Enum<T>>
T
valueOf(Class<T> enumType,String name)
          返回带指定名称的指定枚举类型的枚举常量。


别忘了:枚举定义为  静态的   只要一加载 类 就会调用  构造方法。

public class EnumTest {
	
	public static void main(String[] args) {
		
		
		WeekDay1 weekDay = WeekDay1.MON;
		System.out.println(weekDay.nextDay());
		
		System.out.println("----------上面是 星期天-----------------");
		
		WeekDay weekDay2 = WeekDay.FRI;
		
		System.out.println("+++++++++     最后执行               ++++++++++++");
		System.out.println(weekDay2);
		
		System.out.println("---------------又来了一个---------------------");
		
		System.out.println(weekDay2.name());
		System.out.println(weekDay2.ordinal());	
		System.out.println(WeekDay.valueOf("SUN").toString());
		System.out.println(WeekDay.values().length);


	}
	
	public enum WeekDay{
		 /*
		  
		  SUN() 代表的是一个构造方法,也就是 默认的构造方法:  
		  private WeekDay(){
			System.out.println("frist");
		  }

		  * */   
		// 谨记:  -枚举元素MON和MON()的效果一样,都是调用默认构造方法。
		SUN(),MON(1),TUE,WED,THI,FRI,SAT;
		private WeekDay(){
			System.out.println("frist");
		}
		
		private WeekDay(int day){
			System.out.println("second");
		}
	}

}


注意:利用 abstract 抽象方法,可以避免使用大量的if,else 语句,是程序更加的健壮与美观,和灵活,便于扩展(具有扩展性)

            这样  让 nextDay()方法 分别由子类来完成,而不是由父类去逐一的实现。


如果想在 一个类中编写完各种枚举类和测试用类,那么可以将枚举类定义成调用类的  内部类。


public abstract class WeekDay1 {
	private WeekDay1() {
	}

	public final static WeekDay1 SUN = new WeekDay1() {

		@Override
		public WeekDay1 nextDay() {
			// TODO Auto-generated method stub
			return MON;
		}

	};
	public final static WeekDay1 MON = new WeekDay1() {

		@Override
		public WeekDay1 nextDay() {
			// TODO Auto-generated method stub
			return SUN;
		}

	};

	public abstract WeekDay1 nextDay();

	/*
	 * public WeekDay nextDay(){ if(this == SUN){ return MON; }else{ return SUN;
	 * } }
	 */

	public String toString() {
		return this == SUN ? "SUN" : "MON";
	}
}

SUN
----------上面是 星期天-----------------
frist
second -------->(调用  带参数的构造方法)
frist
frist
frist
frist
frist
+++++++++     最后执行               ++++++++++++
FRI
---------------又来了一个---------------------
FRI
5
SUN

7


实现带有抽象方法的枚举:

    实现抽象的next()方法:每个元素分别是由枚举类的子类来生成的实例对象,这些子类采用 类似 内部类的方式进行定义。 
     每个元素是这个类的实例对象,这个实例对象现在不能拿着 这个类TrafficLamp 直接去new 了。
     只能拿这个类的子类对象去new 并且 把这个对象的名字叫为:REN,GREEN,YELLOW.
     应该  在哪里  定义 子类的实现代码呢???

      REN 是  TrafficLamp类的子类的 实例对象。


枚举只有一个成员时,就可以作为一种单例的实现方式。

public class EnumTest {
	
	public static void main(String[] args) {
		
		// 表明是 new java.util 的子类。既可以调用父类的有参的构造方法,也可以调用父类无参的构造方法。
		new Date(){};
	}
	
	public enum TrafficLamp{
		
		// new 子类的实例对象,并且调用 父类的  构造方法。 
		RED(33) {
			@Override
			public TrafficLamp nextLamp() {
				return GREEN;
			}
		},
		GREEN(50){
			@Override
			public TrafficLamp nextLamp() {
				return YELLOW;
			}
		},
		YELLOW(6){
			@Override
			public TrafficLamp nextLamp() {
				return RED;
			}
		};
		public abstract TrafficLamp nextLamp();
		private int time;
		private TrafficLamp(int time){
			this.time = time;
		}
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值