JAVA面向对象学习——java面向对象概念———Java 枚举(enum)
Java 枚举(enum)
Java 枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等。
Java 枚举类使用 enum 关键字来定义,各个常量使用逗号 , 来分割。
例如定义一个颜色的枚举类。
enum Color
{
RED, GREEN, BLUE;
}
以上枚举类 Color 颜色常量有 RED, GREEN, BLUE,分别表示红色,绿色,蓝色。
使用实例:
enum Color { RED, GREEN, BLUE; } public class Test2 { // 执行输出结果 public static void main(String[] args) { Color c1 = Color.RED; System.out.println(c1); } }
====================================================
内部类中使用枚举
枚举类也可以声明在内部类中:
public class Test2 { enum Color { RED, GREEN, BLUE; } // 执行输出结果 public static void main(String[] args) { Color c1 = Color.RED; System.out.println(c1); } }
每个枚举都是通过 Class 在内部实现的,且所有的枚举值都是 public static final 的。
以上的枚举类 Color 转化在内部类实现:
class Color
{
public static final Color RED = new Color();
public static final Color BLUE = new Color();
public static final Color GREEN = new Color();
}
迭代枚举元素
可以使用 for 语句来迭代枚举元素:
enum Color { RED, GREEN, BLUE; } public class Test2 { public static void main(String[] args) { for (Color myVar : Color.values()) { System.out.println(myVar); } } }
在 switch 中使用枚举类
枚举类常应用于 switch 语句中:
enum Color { RED, GREEN, BLUE; } public class Test2 { public static void main(String[] args) { Color myVar = Color.BLUE; switch(myVar) { case RED: System.out.println("红色"); break; case GREEN: System.out.println("绿色"); break; case BLUE: System.out.println("蓝色"); break; } } }
=============================================================
values(), ordinal() 和 valueOf() 方法
enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Serializable 和 java.lang.Comparable 两个接口。
values(), ordinal() 和 valueOf() 方法位于 java.lang.Enum 类中:
- values() 返回枚举类中所有的值。
- ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样。
- valueOf()方法返回指定字符串值的枚举常量。
enum Color { RED, GREEN, BLUE; } public class Test2 { public static void main(String[] args) { // 调用 values() Color[] arr = Color.values(); // 迭代枚举 for (Color col : arr) { // 查看索引 System.out.println(col + " at index " + col.ordinal()); } // 使用 valueOf() 返回枚举常量,不存在的会报错 IllegalArgumentException System.out.println(Color.valueOf("RED")); // System.out.println(Color.valueOf("WHITE")); } }
=========================================================
枚举类成员
枚举跟普通类一样可以用自己的变量、方法和构造函数,构造函数只能使用 private 访问修饰符,所以外部无法调用。
枚举既可以包含具体方法,也可以包含抽象方法。 如果枚举类具有抽象方法,则枚举类的每个实例都必须实现它。
enum Color { RED, GREEN, BLUE; private Color() { System.out.println("Constructor called for : " + this.toString()); } public void colorInfo() { System.out.println("Universal Color"); } } public class Test2 { public static void main(String[] args) { Color c1 = Color.RED; System.out.println(c1); c1.colorInfo(); } }
enum Color { RED, GREEN, BLUE; private Color() { System.out.println("Constructor called for : " + this.name()); } public void colorInfo() { System.out.println("Universal Color"); } } public class Test2 { public static void main(String[] args) { Color c1 = Color.GREEN; System.out.println(c1.name()); System.out.println(c1); c1.colorInfo(); System.out.println(c1.toString()); System.out.println(c1.ordinal()); } }
enum Color { RED, GREEN, BLUE; public void colorInfo() { System.out.println("Universal Color"); } } public class Test2 { public static void main(String[] args) { Color c1 = Color.GREEN; System.out.println(c1.name()); System.out.println(c1); c1.colorInfo(); System.out.println(c1.toString()); System.out.println(c1.ordinal()); } }
==============================================
枚举类中的抽象方法实现,需要枚举类中的每个对象都对其进行实现。
enum Color{ RED{ public String getColor(){//枚举对象实现抽象方法 return "hong se "; } }, GREEN{ public String getColor(){//枚举对象实现抽象方法 return "lv se"; } }, BLUE{ public String getColor(){//枚举对象实现抽象方法 return "lan se"; } }; public abstract String getColor();//定义抽象方法 } public class Test2 { public static void main(String[] args) { for (Color c:Color.values()){ System.out.print(c.getColor() + "-------"); } } }
=================================================================
=================================================================
枚举类
Java 5新增了一个enum关键字(它与class、interface关键字的地位相同),用以定义枚举类。
正如前面看到的,枚举类是一种特殊的类,它一样可以有自己的成员变量、方法,可以实现一个或者多个接口,也可以定义自己的构造器。
一个Java源文件中最多只能定义一个public访问权限的枚举类,且该Java源文件也必须和该枚举类的类名相同。
但枚举类终究不是普通类,它与普通类有如下简单区别:
? 枚举类可以实现一个或多个接口,使用enum定义的枚举类默认继承了java.lang.Enum类,而不是默认继承Object类,因此枚举类不能显式继承其他父类。
其中java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口。
? 使用enum定义、非抽象的枚举类默认会使用final修饰。
? 枚举类的构造器只能使用private访问控制符,如果省略了构造器的访问控制符,则默认使用private修饰;
如果强制指定访问控制符,则只能指定private修饰符。由于枚举类的所有构造器都是private的,而子类构造器总要调用父类构造器一次,因此枚举类不能派生子类。
? 枚举类的所有实例必须在枚举类的第一行显式列出,否则这个枚举类永远都不能产生实例。列出这些实例时,系统会自动添加public static final修饰,无须程序员显式添加。
枚举类默认提供了一个values()方法,该方法可以很方便地遍历所有的枚举值。
public enum SeasonEnum { // 在第一行列出4个枚举实例 SPRING, SUMMER, FALL, WINTER; }
public class EnumTest { public void judge(SeasonEnum s) { // switch语句里的表达式可以是枚举值 switch (s) { case SPRING: System.out.println("春暖花开,正好踏青"); break; case SUMMER: System.out.println("夏日炎炎,适合游泳"); break; case FALL: System.out.println("秋高气爽,进补及时"); break; case WINTER: System.out.println("冬日雪飘,围炉赏雪"); break; } } public static void main(String[] args) { // 枚举类默认有一个values方法,返回该枚举类的所有实例 for (var s : SeasonEnum.values()) { System.out.println(s); } // 使用枚举实例时,可通过EnumClass.variable形式来访问 new EnumTest().judge(SeasonEnum.SPRING); } }
public class EnumTest { public void judge(SeasonEnum s) { switch (s) { case SPRING: System.out.println("1"); break; case SUMMER: System.out.println("2"); break; case FALL: System.out.println("3"); break; case WINTER: System.out.println("4"); break; } } public static void main(String[] args) { System.out.println("------------------"); for (SeasonEnum s : SeasonEnum.values()) { System.out.println(s); } System.out.println("------------------"); new EnumTest().judge(SeasonEnum.SPRING); } }
枚举类的成员变量、方法、构造器
枚举类也是一种类,只是它是一种比较特殊的类,因此它一样可以定义成员变量、方法、构造器。
public enum Gender { MALE, FEMALE; // 定义一个public修饰的实例变量 public String name; }
public class GenderTest { public static void main(String[] args) { // 通过Enum的valueOf()方法来获取指定枚举类的枚举值 Gender g = Enum.valueOf(Gender.class, "FEMALE"); // 直接为枚举值的name实例变量赋值 g.name = "女"; // 直接访问枚举值的name实例变量 System.out.println(g + "代表:" + g.name); } }
----------------------------------------------------------------------------------------------------------------------------------------------
public enum Gender { MALE, FEMALE; private String name; public void setName(String name) { switch (this) { case MALE: if (name.equals("男")) { this.name = name; } else { System.out.println("参数错误"); return; } break; case FEMALE: if (name.equals("女")) { this.name = name; } else { System.out.println("参数错误"); return; } break; } } public String getName() { return this.name; } }
public class GenderTest { public static void main(String[] args) { Gender g = Gender.valueOf("FEMALE"); g.setName("女"); System.out.println(g + "代表:" + g.getName()); // 此时设置name值时将会提示参数错误。 g.setName("男"); System.out.println(g + "代表:" + g.getName()); } }
public enum Operation { PLUS { public double eval(double x, double y) { return x + y; } }, MINUS { public double eval(double x, double y) { return x - y; } }, TIMES { public double eval(double x, double y) { return x * y; } }, DIVIDE { public double eval(double x, double y) { return x / y; } }; // 为枚举类定义一个抽象方法 // 这个抽象方法由不同的枚举值提供不同的实现 public abstract double eval(double x, double y); public static void main(String[] args) { System.out.println(Operation.PLUS.eval(3, 4)); System.out.println(Operation.MINUS.eval(5, 4)); System.out.println(Operation.TIMES.eval(5, 4)); System.out.println(Operation.DIVIDE.eval(5, 4)); } }
枚举类里面定义抽象方法时,不能使用abstract关键字将枚举类定义为抽象类(因为系统会自动为它添加abstract关键字);
但是因为枚举类需要显式创建枚举值,而不是作为父类,所以定义每个枚举值时必须为抽象方法提供实现,否则错误。