天天看點

黑馬程式員_枚舉為什麼要有枚舉用普通類如何實作枚舉功能枚舉的基本應用枚舉的進階應用

---------------------- ASP.Net+Unity開發、 .Net教育訓練、期待與您交流! ----------------------

為什麼要有枚舉

問題:要定義星期幾或性别的變量,該怎麼定義?假設用1-7分别表示星期一到星期日,但有人可能會寫成int weekday = 0;或即使使用常量方式也無法阻止意外。

枚舉就是要讓某個類型的變量的取值隻能為若幹個固定值中的一個,否則,編譯器就會報錯。枚舉可以讓編譯器在編譯時就可以控制源程式中填寫的非法值,普通變量的方式在開發階段無法實作這一目标。

用普通類如何實作枚舉功能

定義一個Weekday的類來模拟枚舉功能。 

私有的構造方法

每個元素分别用一個公有的靜态成員變量表示

可以有若幹公有方法或抽象方法。采用抽象方法定義nextDay就将大量的if.else語句轉移成了一個個獨立的類。

package cn.itcast.enumeration;

public class Weekday {

// 私有構造方法,不允許外界構造對象

private Weekday() {

}

// 自己構造對象

public static final Weekday SUNDAY = new Weekday();

public static final Weekday MONDAY = new Weekday();

public static final Weekday TUESDAY = new Weekday();

public static final Weekday WEDNESDAY = new Weekday();

public static final Weekday THURSDAY = new Weekday();

public static final Weekday FRIDAY = new Weekday();

public static final Weekday SATURDAY = new Weekday();

// 定義方法。注意個方法有大量的if-else判斷,為了簡化,我們可以把此方法定義為抽象的。具體看Weekday2

public Weekday nextDay() {

Weekday nextDay = null;

if (this == SUNDAY) {

nextDay = MONDAY;

} else if (this == MONDAY) {

nextDay = TUESDAY;

} else if (this == TUESDAY) {

nextDay = WEDNESDAY;

} else if (this == WEDNESDAY) {

nextDay = THURSDAY;

} else if (this == THURSDAY) {

nextDay = FRIDAY;

} else if (this == FRIDAY) {

nextDay = SATURDAY;

} else if (this == SATURDAY) {

nextDay = SUNDAY;

} else {

throw new IllegalArgumentException();

}

return nextDay;

}

// 覆寫方法,便于外界調用

@Override

public String toString() {

String toString = null;

if (this == SUNDAY) {

toString = "sunday";

} else if (this == MONDAY) {

toString = "monday";

} else if (this == TUESDAY) {

toString = "tuesday";

} else if (this == WEDNESDAY) {

toString = "wednesday";

} else if (this == THURSDAY) {

toString = "thursday";

} else if (this == FRIDAY) {

toString = "friday";

} else if (this == SATURDAY) {

toString = "saturday";

} else {

throw new IllegalArgumentException();

}

return toString;

}

}

package cn.itcast.enumeration;

public abstract class Weekday2 {

public static final Weekday2 SUNDAY = new Weekday2() {

@Override

public Weekday2 nextDay() {

return MONDAY;

}

};

public static final Weekday2 MONDAY = new Weekday2() {

@Override

public Weekday2 nextDay() {

return TUESDAY;

}

};

public static final Weekday2 TUESDAY = new Weekday2() {

@Override

public Weekday2 nextDay() {

return WEDNESDAY;

}

};

public static final Weekday2 WEDNESDAY = new Weekday2() {

@Override

public Weekday2 nextDay() {

return THURSDAY;

}

};

public static final Weekday2 THURSDAY = new Weekday2() {

@Override

public Weekday2 nextDay() {

return FRIDAY;

}

};

public static final Weekday2 FRIDAY = new Weekday2() {

@Override

public Weekday2 nextDay() {

return SATURDAY;

}

};

public static final Weekday2 SATURDAY = new Weekday2() {

@Override

public Weekday2 nextDay() {

return SUNDAY;

}

};

public abstract Weekday2 nextDay();

@Override

public String toString() {

String toString = null;

if (this == SUNDAY) {

toString = "sunday";

} else if (this == MONDAY) {

toString = "monday";

} else if (this == TUESDAY) {

toString = "tuesday";

} else if (this == WEDNESDAY) {

toString = "wednesday";

} else if (this == THURSDAY) {

toString = "thursday";

} else if (this == FRIDAY) {

toString = "friday";

} else if (this == SATURDAY) {

toString = "saturday";

} else {

throw new IllegalArgumentException();

}

return toString;

}

}

枚舉的基本應用

舉例:定義一個Weekday的枚舉。

擴充:枚舉類的values,valueOf,name,toString,ordinal等方法

總結:枚舉是一種特殊的類,其中的每個元素都是該類的一個執行個體對象,例如可以調用WeekDay.SUN.getClass().getName和WeekDay.class.getName()。

枚舉的進階應用

枚舉就相當于一個類,其中也可以定義構造方法、成員變量、普通方法和抽象方法。

枚舉元素必須位于枚舉體中的最開始部分,枚舉元素清單的後要有分号與其他成員分隔。把枚舉中的成員方法或變量等放在枚舉元素的前面,編譯器報告錯誤。

帶構造方法的枚舉

構造方法必須定義成私有的

如果有多個構造方法,該如何選擇哪個構造方法?

枚舉元素MON和MON()的效果一樣,都是調用預設的構造方法。

帶方法的枚舉

定義枚舉TrafficLamp

實作普通的next方法

實作抽象的next方法:每個元素分别是由枚舉類的子類來生成的執行個體對象,這些子類采用類似内部類的方式進行定義。

增加上表示時間的構造方法

枚舉隻有一個成員時,就可以作為一種單例的實作方式。

package cn.itcast.enumeration;

public class EnumTest2 {

public static void main(String[] args) {

// Weekday mon = Weekday.MONDAY;

// System.out.format("%s的下一天是%s.%n", mon, mon.nextDay());

Weekday2 mon = Weekday2.MONDAY;

System.out.println(mon.name());

System.out.println(mon.ordinal());

System.out.println(Weekday2.valueOf("MONDAY"));

System.out.println(Weekday2.values().length);

}

public enum Weekday2 {

SUNDAY(0), MONDAY(1), TUESDAY(), WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;

private Weekday2() {

System.out.println("無參構造方法");

}

private Weekday2(int day) {

System.out.println("有參構造方法");

}

}

public enum TrafficLamp {

RED(30) {

@Override

public TrafficLamp nextLamp() {

return GREEN;

}

},

GREEN(45) {

@Override

public TrafficLamp nextLamp() {

return YELLOW;

}

},

YELLOW(5) {

@Override

public TrafficLamp nextLamp() {

return RED;

}

};

private int time;

private TrafficLamp(int time) {

this.time = time;

}

public abstract TrafficLamp nextLamp();

public int getTime() {

return time;

}

}

}

---------------------- ASP.Net+Unity開發、 .Net教育訓練、期待與您交流! ----------------------