Java的枚举类比C#枚举类更像类一点,因为它还可以定义属性和方法
01.public enum Gender
02.{
03. MALE,FEMALE;
04. private String name;
05. public void setName(String name)
06. {
07. switch(this)
08. {
09. case MALE:
10. if(name.equals("男"))
11. {
12. this.name = name;
13. }
14. else
15. {
16. System.out.println("参数错误");
17. return;
18. }
19. break;
20. case FEMALE:
21. if(name.equals("女"))
22. {
23. this.name = name;
24. }
25. else
26. {
27. System.out.println("参数错误");
28. return;
29. }
30. break;
31. }
32. }
33. public String getName()
34. {
35. return this.name;
36. }
37.}
01.<pre class="java" name="code">public class TestGender
02.{
03. public static void main(String[] args)
04. {
05. Gender g = Enum.valueOf(Gender.class,"FEMALE");
06. g.setName("女");
07. System.out.println(g + "代表:" + g.getName());
08. //此时设置 name 属性时将会提示参数错误码
09. g.setName("男");
10. System.out.println(g + "代表:" + g.getName());
11. }
12.}</pre><br><strong>对枚举类来说,应该设计成不可变类,因此上面的属性值不应该允许改变,这样是不安全的,因此对属性应使用final修饰符,必须在构造器里为这些属性指定初始值,因此应该为枚举类显式定义带参数的构造器MALE,FEMALE 这些枚举值代表枚举类的所有可能实例,所以MALE(参数),就等同于调用构造器,类实例(参数)</strong>
01.MALE("男"),FEMALE("女")这样的写法确实给人一种怪异的感觉<pre style="background-color: rgb(255, 255, 255);" class="java" name="code"><pre class="java" name="code">public enum Gender
02.{
03. //此处的枚举值必须调用对应构造器来创建
04. MALE("男"),FEMALE("女");
05. private final String name;
06. //枚举类的构造器只能使用private修饰
07. private Gender(String name)
08. {
09. this.name = name;
10. }
11. public String getName()
12. {
13. return this.name;
14. }
15.}</pre><br><pre class="java" name="code">public class TestGender
16.{
17. public static void main(String[] args)
18. {
19. Gender g = Enum.valueOf(Gender.class,"FEMALE");
20. System.out.println(g + "代表:" + g.getName());
21.
22. g = Enum.valueOf(Gender.class,"MALE");
23. System.out.println(g + "代表:" + g.getName());
24. }
25.}</pre>现在客户端不再有修改枚举类属性的权力了,呵呵</pre><strong>枚举类还可以实现一个或多个接口,C#的枚举类不支持这种做法</strong>
01.<pre class="java" name="code">public interface GenderDesc
02.{
03. void info();
04.}
05.
06.
07.public enum Gender implements GenderDesc
08.{
09. //此处的枚举值必须调用对应构造器来创建
10. MALE("男")
11. //花括号部分实际上是一个类体部分
12. {
13. public void info()
14. {
15. System.out.println("这个枚举值代表男性");
16. }
17. },
18. FEMALE("女")
19. {
20. public void info()
21. {
22. System.out.println("这个枚举值代表女性");
23. }
24. };
25. private final String name;
26. private Gender(String name)
27. {
28. this.name = name;
29. }
30.}
31.</pre><br>当创建MALE和FEMALE两个枚举值时,后面又跟着一对花括号,括号里又包含一个info方法定义.括号部分实际是一个类体部分,当创始MALE,FEMALE枚举值时,并不是直接创建了Gender枚举类实例,而是相当于创建Gender的匿名子类实例.所以这个部分与匿名内部类语法大致相似.
编译生成三个文件Gender.class,Gender$1.class,Gender$2.class,和之前内部类的生成名字结构一样,证明了以上结论,MALE和FEMALE是Gender匿名子类的实例,而不是Gender类的实例
枚举类可包含抽象方法,当然这个C#也是不支持的
01.<pre class="java" name="code">public enum Operation
02.{
03. PLUS
04. {
05. public double eval(double x,double y)
06. {
07. return x + y;
08. }
09. },
10. MINUS
11. {
12. public double eval(double x,double y)
13. {
14. return x - y;
15. }
16. },
17. TIMES
18. {
19. public double eval(double x,double y)
20. {
21. return x*y;
22. }
23. },
24. DIVIDE
25. {
26. public double eval(double x,double y)
27. {
28. return x/y;
29. }
30. };
31. //为枚举类定义一个抽象方法,这个抽象方法由不同枚举值提供不同的实现
32. public abstract double eval(double x,double y);
33. public static void main(String[] args)
34. {
35. System.out.println(Operation.PLUS.eval(3,4));
36. System.out.println(Operation.MINUS.eval(5,4));
37. System.out.println(Operation.TIMES.eval(5,4));
38. System.out.println(Operation.DIVIDE.eval(5,4));
39. }
40.}
41.</pre><br><br><p></p>