枚舉類,java枚舉類

來源:互聯網
上載者:User

枚舉類,java枚舉類

這種執行個體有限而且固定的類,在Java裡稱為枚舉類。例如:季節類,它只有4個對象,還有行星類目前只有8個對象。

5.9.1 手動實現枚舉類
public static final int SEASON_SPRING = 1;public static final int SEASON_SUMMER = 2;public static final int SEASON_FALL = 3;public static final int SEASON_WINTER = 4;

存在幾個問題:(簡單表述)
1. 類型不安全:實際每個季節是int整數
2. 沒有命名空間:
3. 列印輸出的意義不明確:1很難猜測出代表春天。

5.9.2 枚舉類入門

Java5新增一個enum關鍵字(和class、interface關鍵字差不多),用以定義枚舉類。
枚舉類是一種特殊的類,它一樣有自己的成員變數、方法,可以實現一個或者多個介面,也可以定義自己的構造器。
但是枚舉類還是和普通類有簡單區別:

  • 枚舉類可以實現一個或多個介面,使用enum定義的枚舉類預設繼承了java.lang.Enum類,而不是預設繼承Object類,因此枚舉類不能顯式繼承其他父類。其中java.lang.Enum類實現了java.lang.Serializable和java.lang.Comparable兩個介面。
  • 使用Enum定義,非抽象的枚舉類預設會使用final修飾,所以不能派生子類
  • 枚舉類的構造器只能使用private,如果省略了構造器的存取控制符,則預設使用private,
  • 枚舉類的所有執行個體必須在枚舉類的第一行顯式列出,否則這個枚舉類永遠都不能產生執行個體,列出這些執行個體時,系統會自動添加public staic final修飾,無須顯式添加
    枚舉類預設提供了一個values()方法,該方法可以很方便地遍曆所有的枚舉類
package code;public enum SeasonEnum{    //在第一行列出4個枚舉類執行個體    SPRING,SUMMER,FALL,WINTER;}

EnumTest.java

package code;public class EnumTest{    public void judge(SeasonEnum e){        //switch語句裡的運算式可以是枚舉類        switch(e){            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(SeasonEnum s:SeasonEnum.values()){            System.out.println(s);        }        //使用枚舉類時,可通過EnumClass.variable形式來訪問        new EnumTest().judge(SeasonEnum.SPRING);    }}

java.lang.Enum類中提供了如下的幾個方法,所有枚舉類可以直接使用這些方法:

  • int compareTo(E o ):該方法用於與指定枚舉對象比較順序,同一個枚舉執行個體只能與相同類型的枚舉執行個體進行比較,如果該枚舉對象位於指定枚舉對象之後,則返回正整數,如果該枚舉對象位於指定枚舉對象之前,則返回負整數,否則返回零。
  • String name():返回此枚舉執行個體的名稱,,這個名稱就是定義枚舉類時列出的所有 枚舉類之一,但是大多數情況下使用toString()方法
  • int ordinal():返回枚舉值在枚舉類中的索引值
  • String toString() :返回枚舉常量的名稱,與name方法相似,toString方法更常用
  • public static
5.9.3 枚舉類的成員變數、方法和構造器

Gender.java

package code;public enum Gender{    MALE,FEMALE;    public String name;}

GenderTest.java

package code;public class GenderTest{    public static void main(String [] args){        Gender g = Enum.valueOf(Gender.class,"FEMALE");        g.name = "女";        System.out.println(g + "代表:" + g.name);    }}

java應該把所有類設計成良好封裝的類,所以不應該允許直接存取Gender類的name成員變數,而應該通過方法來控制對name的訪問。
接下來的代碼是改進後的設計
Gender.java

package code;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("參數錯誤");                }                break;            case FEMALE:                if(name.equals("女")){                    this.name = name;                }else{                    System.out.println("參數錯誤");                }                break;        }    }    public String getName(){        return this.name;    }}

GenderTest.java

package code;public class GenderTest{    public static void main(String [] args){        Gender g = Enum.valueOf(Gender.class,"FEMALE");        g.setName("女");        System.out.println(g + "代表:" + g.name());        g.setName("男");        System.out.println(g + "代表:" + g.getName());    }}

FEMALE代表:FEMALE
參數錯誤
FEMALE代表:女

實際上這種做法依然不好,枚舉類通常應該設計成不可變類,也就是說,它的成員變數值不應該允許改變,這樣會更安全,而且代碼更加簡潔。因此建議將枚舉類的成員變數都使用private final修飾。
如果將所有的成員變數都使用了final修飾符來修飾,所以必須在構造器裡為這些成員變數指定初始值(或者在定義成員變數時指定預設值,或者在初始化塊中指定初始值,但是這兩種情況不常見),因此應該為枚舉類顯式定義帶參數的構造器。
一旦為枚舉類顯式定義了帶參數的構造器,列出枚舉值時就必須對應地傳入參數。

package code;public enum Gender{    MALE("男"),FEMALE("女");    private final String name;    private Gender(String name){        this.name = name;    }    public String getName(){        return this.name;    }

當為Gender枚舉類建立了一個Gender(String name)構造器之後,列出枚舉類就是從MALE(“男”),FEMALE(“女”);這句程式碼完成,也就是說在枚舉類中列出枚舉類時,實際上就是調用構造器建立枚舉類對象。只是這裡無須使用new關鍵字,無須顯式調用構造器。
等同於以下兩句代碼

public static final Gender MALE = new Gender("男");public static final Gender FEMALE = new Gender("女");
5.9.4 實現介面的枚舉類

枚舉類和普通類一樣可以實現一個或多個介面

package code;public enum Gender2 implements GenderDesc{    MALE("男"),FEMALE("女");    private final String name;    private Gender(String name){        this.name = name;    }    public String getName(){        return this.name;    }    public void info(){        System.out.println("這是一個用於定義性別的枚舉類");    }} 

枚舉類實現介面和普通類實現介面完全一樣。
如果由枚舉類來實現介面裡的方法,則每個枚舉值在調用該方法時都有相同的行為方式,(因為方法體完全一樣)如果需要每個枚舉值在調用該方法時呈現不同的行為方式,則可以讓每個枚舉值分別實現該方法,每個枚舉值提供不同的實現方式,從而讓不同的枚舉值調用該方法時具有不同的行為方式。
樣本如下:

package code;public enum Gender2 implements GenderDesc{    MALE("男"){        public void info(){            System.out.println("這個枚舉值代表男性");        }    },FEMALE("女"){        public void info(){            System.out.println("這個枚舉值代表女性");        }    };    private final String name;    private Gender2(String name){        this.name = name;    }    public String getName(){        return this.name;    }    /*public void info(){        System.out.println("這是一個用於定義性別的枚舉類");    }*/} 

上述代碼中MALE和FEMALE後面的花括弧部分實際上是一個類體部分,類似匿名內部類。在這種情況下,當建立MALE,FEMALE枚舉值時,並不是直接建立Gender枚舉類的執行個體,而是相當於建立了Gender的匿名子類的執行個體。所以括弧內的只是枚舉類的匿名內部子類。

並不是所有的枚舉類都使用了final修飾,非抽象的枚舉類才預設使用final修飾,對於一個抽象的枚舉類,只要它包含抽象方法,他就是抽象枚舉類,系統會預設使用abstract修飾。

5.9.5 包含抽象方法的枚舉類
package code;public enum Operation{    PLUS{        public double eval(double a ,double b){            return (a+b);        }    },    MINUS{        public double eval(double a ,double b){                return (a-b);            }    },    TIMES{        public double eval(double a ,double b){            return (a*b);        }    },    DIVIDE{        public double eval(double a ,double b){            return (a/b);        }    };    public abstract double eval(double a,double b);    public static void main(String [] args){        System.out.println(Operation.PLUS.eval(3,4));        System.out.println(Operation.MINUS.eval(3,4));        System.out.println(Operation.TIMES.eval(3,4));        System.out.println(Operation.DIVIDE.eval(3,4));    }}

7.0
-1.0
12.0
0.75

枚舉類裡定義抽象方法的時候不能使用abstract關鍵字將枚舉類定義成抽象類別(因為系統自動會為它添加abstract關鍵字),但因為枚舉類需要顯式建立枚舉類,而不是作為父類,所以定義每個枚舉值時必須為抽象方法提供實現,否則出錯。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.