1. 程式人生 > >14. JAVA 列舉(Enum、類集EnumMap&EnumSet 、實現介面、定義抽象方法) ----- 學習筆記

14. JAVA 列舉(Enum、類集EnumMap&EnumSet 、實現介面、定義抽象方法) ----- 學習筆記

本章目標:

  • 瞭解列舉可以解決哪些技術問題
  • 掌握列舉的定義方式
  • 清楚地掌握enum關鍵字與Enum類的關係
  • 掌握JDK1.5之後的列舉操作類:EnmuSet、EnumMap
  • 讓列舉類實現一個介面或在列舉類中定義抽象方法

        列舉是在JDK1.5之後另外一個重要的特性,在列舉中可以限制一個類的物件產生範圍,加入了列舉之後Java又對之前的類集進行了擴充,產生了一些新的列舉支援類 --- EnumSet、EnumMap,為列舉的使用提供了方便。

14.1 列舉型別簡介

        在JDK1.5之前,Java有兩種方式定義新型別: 類和介面。 對於大部分面向物件程式設計來說,這兩種方法看起來似乎足夠了。但是在一些特殊的情況下,這些方法就不適合了。 例如,想定義一個Color類,它只能有Red、Green、Blue3種植,其他的任何值都是非法的,那麼JDK1.5之前雖然可以構造這樣的程式碼,但是要做很多的工作,就可能帶來各種不安全的問題。而在JDK1.5之後,引入的列舉型別(Enum)就能避免這些問題。

14.2 使用簡單程式完成列舉的功能

       列舉是在JDK1.5之後引入的, 如果在JDK1.5之前完成列舉的功能,則必須依靠類似於以下的程式程式碼完成。

範例: 使用簡單類完成列舉操作

class Color{
    public static final Color RED = new Color("Red");    //定義第一個物件
    public static final Color GREEN = new Color("Green");   //定義第二個物件
    public static final Color BLUE = new Color("Blue");     //定義第三個物件
    private String name;
    private Color(String name){
        this.setName(name);
    }
    public String getName(){
        return this.name;
    }
    public void setName(String name){
        this.name = name;
    }
    public static Color getInstance(int i){  //等到一個顏色,只能從固定的幾個顏色中取得中得
        switch(i){
            case 1:{
                return RED;
            }
            case 2:{
                return GREEN;
            }
            case 3:{
                return BLUE;
            }
            default:{
                return null;
            }
        }
    }
}

public class ColorDemo01{
    public static void main(String args[]){
        Color c1 = Color.RED;
        System.out.println(c1.getName());
        
        Color c2 = Color.getInstance(3);
        System.out.println(c2.getName());
    }
}

         以上程式將Color類中的構造方法私有化,之後再類中準備了若干個例項化物件,以後如果要取得Color類的例項, 則只能從BLUE、GREEN、RED3個物件中取得,這樣就有效地限制了物件的取得範圍。

        以上使用的Color物件指定的範圍,是通過一個個常量對每個物件進行編號的。 也就是說,一個個的物件就相當於用常量表示了。 所以,按照這個思路也可以直接使用一個介面規定出一組常量的範圍。

範例: 使用介面表示一組範圍

package org.forfan06.colordemo;
public interface Color{
     public static final int RED = 1;
     public static final int GREEN = 2;
     public static final int BLUE = 3;
}

以上表示出的各個顏色是通過介面指定好的常量範圍,與之前相比更加簡單。但是這樣做也會存在另外一個iewenti,如果現在使用如下的程式碼:

package org.forfan06.colordemo;
public class ColorDemo02{
     public static void main(String args[]){
          System.out.println(Color.RED + Color.GREEN);
     }
}

        兩個顏色的常量相加之後形成了“3”,這樣的結果看起來會令人非常困惑,操作很不明確。

        另外,使用以上這種方法,使用者如果想知道到底有多少個顏色可以使用,則實現的程式碼非常複雜。在JDK1.5之後就有了專門解決這樣問題的方法。

14.3 定義一個列舉型別

          在JDK1.5之後,引入了一個新的關鍵字型別  ---  enum, 可以直接定義列舉型別。

//宣告列舉型別
[public] enum 列舉型別名稱{
     列舉物件1, 列舉物件2, ..., 列舉物件n;
}

範例: 定義一個Color的列舉型別

package org.forfan06.enumdemo;
public enum Color{
     RED, GREEN, BLUE;
}

以上的Color定義出來的列舉型別,其中包含RED、GREEN、BLUE3個數據。

可以使用  “ 列舉.variable ” 的形式取出列舉中的指定內容。

範例: 取出一個列舉內容

package org.forfan06.enumdemo;
enum Color{
     RED, GREEN, BLUE;
}

public class GetEnumContent{
     public static void main(String args[]){
          Color c = Color.BLUE;
          System.out.println(c);
     }
}

執行結果:

BLUE

列舉型別的資料也可以使用  “ 列舉.values() ” 的形式,將全部的列舉型別變為物件陣列的形式, 之後使用foreach進行輸出

範例: 使用foreach輸出列舉內容

package org.forfan06.enumdemo;
enum Color{
     RED, GREEN, BLUE;
}

public class PrintEnum{
     public static void main(String args[]){
          for(Color c:Color.values()){   // 列舉.values()表示得到全部列舉的內容
               System.out.print(c + "、");   //輸出結果: RED、GREEN、BLUE、
          }
     }
}

          列舉中的每個型別也可以使用switch進行判斷,但是在switch語句中使用列舉型別時,一定不能再每一個列舉型別值得前面加上列舉型別的類名(例如,Color.BLUE),否則編譯器會報錯!!!!

package org.forfan06.enumdemo;
enum Color{
     RED, GREEN, BLUE;
}

public class SwithcPrintDemo{
     public static void main(String args[]){
          for(Color c:Color.values()){
               print(c);
          }
     }

     public static void print(Color color){
          switch(color){
               case RED:{
                    System.out.println("RED");
                    break;
               }
               case GREEN:{
                    System.out.println("GREEN");
                    break;
               }
               case BLUE:{
                    System.out.println("BLUE");
                    break;
               }
               default:{
                    System.out.println("Unknown");
                    break;
               }
          }
     }
}

       以上的Color.values()方法表示取得列舉中的全部內容,返回的是一個物件陣列,這是列舉本身支援的一個方法,除了這個方法之外, 到底還有哪些方法可以供開發者使用呢? 要了解這些,就必須深入分析列舉類   --- Enum類

14.4 Enum

         從前面的講解中可以知道,使用enum關鍵字可以定義一個列舉,實際上此關鍵字表示的是java.lang.Enum型別,即使用enum宣告的列舉型別就相當於定義了一個類!!而此類預設繼承了java.lang.Enum類。

//java.lang.Enum類的定義
public abstract class Enum<E extends Enum<E>> extends Object implements Comparable<E>, java.io.Serializable

Enum類的定義,此類實現了Comparable和Serializable兩個介面, 證明了列舉型別可以使用比較器和序列化操作!!!!!!!!!!!

Enum類中包含的方法:


下面來逐步觀察這些方法的使用:

      14.4.1 取得列舉的資訊

            在列舉類建立完成之後,實際上都會為其呼叫列舉類中的構造方法,為其賦值。 在Enum類的構造方法中的第一個引數name就是定義的列舉的名稱,第二個引數ordinal則會從0開始依次進行編號。

    之後可以使用Enum類中提供的name()、ordinal()方法取得名稱和編號!!

範例: 驗證name()、ordinal()方法

package org.forfan06.enumdemo;
enum Color{
    RED, GREEN, BLUE;
}

public class GetEnumInfo{
    public static void main(String args[]){
        for(Color c:Color.values()){
            System.out.println(c.ordinal() + "--->" + c.name());
        }
    }
}

執行結果:

0--->RED
1--->GREEN
2--->BLUE

      14.4.2 為每一個列舉物件屬性賦值

1. 通過構造方法為屬性賦值

         每個列舉類中都有其指定好的若干物件,當然,每一個列舉物件中也可以包含多個屬性。而,這些屬性也可以通過構造方法為其賦值。

範例: 通過構造方法為列舉屬性賦值

enum Color{
    RED("紅色"), GREEN("綠色"), BLUE("藍色");
    private Color(String name){
        this.setName(name);
    }
    private String name;
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
}

public class ConstructorEnum{
    public static void main(String args[]){
        for(Color c:Color.values()){
            System.out.println(c.ordinal() + "-->" + c.name() + "(" + c.getName() + ")");
        }
    }
}

執行結果:

0-->RED(紅色)
1-->GREEN(綠色)
2-->BLUE(藍色)

         以上程式程式碼在定義的Color列舉類中設定了一個name屬性,並且通過構造方法設定name屬性的內容。因為Color中已經明確地寫出了有一個引數的構造方法,所以在宣告列舉內容時就必須呼叫這個構造方法,這樣在定義列舉內容時就必須使用如下的語句形式:

       RED("紅色"), GREEN("綠色"), BLUE("藍色");

2. 通過setter方法為屬性賦值

  以上是通過構造方法的方式為屬性賦值的, 當然,也可以通過呼叫setter()方法來為指定的屬性賦值。 但是,這樣一來就必須明確每一個列舉類的物件,如果操作的物件是RED,則名字應該是“紅色”;如果操作的物件是GREEN,則名字應該是“藍色”等等。

範例: 使用setter()方法設定內容

package org.forfan06.enumapidemo;
enum Color{
    RED, GREEN, BLUE;
    /**
    RED("紅色"), GREEN("綠色"), BLUE("藍色");
    private Color(String name){
        this.setName(name);
    }
    **/
    private String name;
    public String getName(){
        return this.name;
    }
    
    public void setName(String name){
        switch(this){
            case RED:{    //判斷是否為該顏色
                if("紅色".equals(name)){    
                    this.name = name;      //設定名稱
                }else{
                    System.out.println("設定內容錯誤。");
                }
                break;
            }
            case GREEN:{    //判斷是否為該顏色
                if("綠色".equals(name)){    
                    this.name = name;      //設定名稱
                }else{
                    System.out.println("設定內容錯誤。");
                }
                break;
            }
            case BLUE:{    //判斷是否為該顏色
                if("藍色".equals(name)){    
                    this.name = name;      //設定名稱
                }else{
                    System.out.println("設定內容錯誤。");
                }
                break;
            }
        }
    }
    /**
    public void setName(String name){
        this.name = name;
    }
    **/
}

public class SetEnum{
    public static void main(String args[]){
        Color c = Color.BLUE;
        c.setName("蘭色");  //設定錯誤的名字
        c.setName("藍色");  //設定正確的名字
        System.out.println(c.getName());
        /**
        for(Color c:Color.values()){
            System.out.println(c.ordinal() + "-->" + c.name() + "(" + c.getName() + ")");
        }
        **/
    }
}

執行結果:

設定內容錯誤。
藍色

      從以上程式碼中,首先通過列舉類取得了裡面的一個物件。之後開始為其設定內容,一開始設定了不符合要求的內容,所以會出現“設定內容錯誤”的提示;而如果設定的內容正確,則可以直接將其賦值給name屬性。

      如果不想通過   “ 列舉類.物件 ” 的形式取得每一個列舉類的物件, 也可以, 使用Enum類定義的 “ 列舉類.valueOf() ”方法的形式進行呼叫!!!!

範例: 使用valueOf()方法找到一個列舉物件

package org.forfan06.enumapidemo;
enum Color{
    RED, GREEN, BLUE;
    /**
    RED("紅色"), GREEN("綠色"), BLUE("藍色");
    private Color(String name){
        this.setName(name);
    }
    **/
    private String name;
    public String getName(){
        return this.name;
    }
    
    public void setName(String name){
        switch(this){
            case RED:{    //判斷是否為該顏色
                if("紅色".equals(name)){    
                    this.name = name;      //設定名稱
                }else{
                    System.out.println("設定內容錯誤。");
                }
                break;
            }
            case GREEN:{    //判斷是否為該顏色
                if("綠色".equals(name)){    
                    this.name = name;      //設定名稱
                }else{
                    System.out.println("設定內容錯誤。");
                }
                break;
            }
            case BLUE:{    //判斷是否為該顏色
                if("藍色".equals(name)){    
                    this.name = name;      //設定名稱
                }else{
                    System.out.println("設定內容錯誤。");
                }
                break;
            }
        }
    }
    /**
    public void setName(String name){
        this.name = name;
    }
    **/
}

public class ValueOfDemo{
    public static void main(String args[]){
        //Color c = Color.BLUE;
        Color c = Enum.valueOf(Color.class, "BLUE");
        c.setName("蘭色");  //設定錯誤的名字
        c.setName("藍色");  //設定正確的名字
        System.out.println(c.getName());
        /**
        for(Color c:Color.values()){
            System.out.println(c.ordinal() + "-->" + c.name() + "(" + c.getName() + ")");
        }
        **/
    }
}

以上程式程式碼,使用valueOf()方法來獲取Enum類的一個列舉物件,第一個引數使用了 “  列舉.class ” 的形式,這裡是Java的反射機制。 在後面的章節會詳細的解釋。

      14.4.3 使用比較器

       在Enum類的定義中已經實現好了Comparable介面,所以列舉類的內容本身是可以進行排序的,下面通過TreeSet演示列舉的排序操作

       TreeSet類可以直接進行排序(類集部分講解到過),排序的規則是通過Comparable介面完成的!!!

範例: 驗證列舉比較器

package org.forfan06.enumapidemo;
import java.util.Set;
import java.util.TreeSet;
import java.util.Iterator;
enum Color{
    RED, GREEN, BLUE;
}

public class ComparableEnum{
    public static void main(String args[]){
        Set<Color> set = new TreeSet<Color>();
        set.add(Color.GREEN);
        set.add(Color.BLUE);
        set.add(Color.RED);
        
        Iterator<Color> iter = set.iterator();
        while(iter.hasNext()){
            System.out.print(iter.next() + "、");
        }
    }
}

執行結果:

RED、GREEN、BLUE、
        以上程式碼塊,資料加入的順序是GREEN、BLUE、RED,但是輸出之後的順序是RED、GREEN、BLUE。說明已經被排序了。是使用Enum類中的ordinal屬性排序的!!!!!!!!!!!

14.5 類集對列舉的支援 --- EnumMap、EnumSet

      在JDK1.5的java.util程式包中提供了兩個新的集合操作類: EnumMap、EnumSet類, 這兩個類與列舉型別的結合應用可以使以前非常繁瑣的程式變得簡單方便。

  1. EnumSet類提供了java.util.Set介面的一個特殊實現;
  2. EnumMap類提供了java.util.Map介面的一個特殊實現,該類中的鍵(key)是一個列舉型別。

      14.5.1 EnumMap

       EnumMap類,是Map介面的子類,所以本身還是以Map的形式進行操作(key --> value)。

       如果要使用EnumMap,則首先要建立EnumMap類的例項化物件,在建立此物件時必須指定要操作的列舉型別。

//EnumMap類的構造方法
public EnumMap(Class<K> keyType)
範例:驗證EnumMap
package org.forfan06.enumcol;
import java.util.EnumMap;
import java.util.Map;
enum Color{
    RED, GREEN, BLUE;
}

public class EnumMapDemo{
    public static void main(String args[]){
        Map<Color, String> desc = null;
        desc = new EnumMap<Color, String>(Color.class);
        desc.put(Color.RED, "紅色");
        desc.put(Color.GREEN, "綠色");
        desc.put(Color.BLUE, "藍色");
        System.out.println("=====輸出全部的內容=====");
        for(Color c:Color.values()){
            System.out.println(c.name() + "-->" + desc.get(c));
        }
        System.out.println("=====輸出全部的鍵值=====");
        for(Color c:desc.keySet()){
            System.out.print(c.name() + "、");
        }
        System.out.println("\n=====輸出全部的內容=====");
        for(String s:desc.values()){
            System.out.print(s + "、");
        }
    }
}

執行結果:

=====輸出全部的內容=====

RED-->紅色
GREEN-->綠色
BLUE-->藍色
=====輸出全部的鍵值=====
RED、GREEN、BLUE、
=====輸出全部的內容=====
紅色、綠色、藍色、

      14.5.2 EnumSet

     EnumSet類,是Set介面的子類, 所以裡面的內容是無法重複的!!!使用EnumSet類時不能直接使用關鍵字new為其進行例項化  v_v 所以在此類中提供了很多的靜態方法:

(1)範例: 驗證EnumSet -- 將全部的集合設定到EnumSet集合中

package org.forfan06.enumdemo;
import java.util.EnumSet;
enum Color{
    RED, GREEN, BLUE;
}

public class EnumSetDemo01{
    public static void main(String args[]){
        EnumSet<Color> eset = null;
        System.out.println("======EnumSet.allOf(Color.class)=====");
        eset = EnumSet.allOf(Color.class);
        
        print(eset);
    }
    
    public static void print(EnumSet<Color> temp){
        for(Color c:temp){
            System.out.print(c + "、");
        }
        System.out.println();
    }
}

執行結果:

======EnumSet.allOf(Color.class)=====
RED、GREEN、BLUE、
        以上程式使用了EnumSet提供的static方法 allOf(),將一個列舉中的全部內容設定到EnumSet集合中。

(2)範例: 驗證EnumSet -- 只設置一個列舉的型別到集合中

package org.forfan06.enumdemo;
import java.util.EnumSet;
enum Color{
    RED, GREEN, BLUE;
}

public class EnumSetDemo02{
    public static void main(String args[]){
        EnumSet<Color> eset = null;
        //System.out.println("======EnumSet.allOf(Color.class)=====");
        //eset = EnumSet.allOf(Color.class);
        System.out.println("======EnumSet.of(Color.class)=====");
        eset = EnumSet.of(Color.BLUE);
        
        print(eset);
    }
    
    public static void print(EnumSet<Color> temp){
        for(Color c:temp){
            System.out.print(c + "、");
        }
        System.out.println();
    }
}

執行結果:

======EnumSet.of(Color.class)=====
BLUE、

(3)範例: 驗證EnumSet -- 建立只能放入指定列舉型別的集合

package org.forfan06.enumdemo;
import java.util.EnumSet;
enum Color{
    RED, GREEN, BLUE;
}

public class EnumSetDemo03{
    public static void main(String args[]){
        EnumSet<Color> eset = null;
        //System.out.println("======EnumSet.allOf(Color.class)=====");
        //eset = EnumSet.allOf(Color.class);
        //System.out.println("======EnumSet.of(Color.class)=====");
        //eset = EnumSet.of(Color.BLUE);
        System.out.println("======EnumSet.noneOf(Color.class)=====");
        eset = EnumSet.noneOf(Color.class);
        
        eset.add(Color.RED);
        eset.add(Color.BLUE);
        
        print(eset);
    }
    
    public static void print(EnumSet<Color> temp){
        for(Color c:temp){
            System.out.print(c + "、");
        }
        System.out.println();
    }
}

執行結果:

======EnumSet.noneOf(Color.class)=====
RED、BLUE、
將集合設定成只能增加Color型別的集合,但,並不設定任何的內容到集合中。

(4)範例: 驗證EnumSet -- 建立不包含指定元素的集合

package org.forfan06.enumdemo;
import java.util.EnumSet;
enum Color{
    RED, GREEN, BLUE;
}

public class EnumSetDemo04_01{
    public static void main(String args[]){
        EnumSet<Color> esetOld = null;
        EnumSet<Color> esetNew = null;
        //System.out.println("======EnumSet.allOf(Color.class)=====");
        //eset = EnumSet.allOf(Color.class);
        //System.out.println("======EnumSet.of(Color.class)=====");
        //eset = EnumSet.of(Color.BLUE);
        esetOld = EnumSet.noneOf(Color.class); //可以加入Color型別的物件
        esetOld.add(Color.RED);
        esetOld.add(Color.BLUE);
        
        esetNew = EnumSet.complementOf(esetOld);  //建立一個不包含指定元素的集合
        
        System.out.println("======EnumSet.noneOf(Color.class)=====");
        print(esetNew);
    }
    
    public static void print(EnumSet<Color> temp){
        for(Color c:temp){
            System.out.print(c + "、");
        }
        System.out.println();
    }
}

執行結果:

======EnumSet.noneOf(Color.class)=====
GREEN、


add()語句的位置影響輸出~

package org.forfan06.enumdemo;
import java.util.EnumSet;
enum Color{
    RED, GREEN, BLUE;
}

public class EnumSetDemo04_02{
    public static void main(String args[]){
        EnumSet<Color> esetOld = null;
        EnumSet<Color> esetNew = null;
        //System.out.println("======EnumSet.allOf(Color.class)=====");
        //eset = EnumSet.allOf(Color.class);
        //System.out.println("======EnumSet.of(Color.class)=====");
        //eset = EnumSet.of(Color.BLUE);
        esetOld = EnumSet.noneOf(Color.class); //可以加入Color型別的物件
        esetNew = EnumSet.complementOf(esetOld);  //建立一個不包含指定元素的集合
        
        esetOld.add(Color.RED);
        esetOld.add(Color.BLUE);
        
        System.out.println("======EnumSet.complementOf(Color.class)=====");
        print(esetNew);
        System.out.println("======EnumSet.noneOf(Color.class)=====");
        print(esetOld);
    }
    
    public static void print(EnumSet<Color> temp){
        for(Color c:temp){
            System.out.print(c + "、");
        }
        System.out.println();
    }
}

此時的執行結果:

======EnumSet.complementOf(Color.class)=====
RED、GREEN、BLUE、
======EnumSet.noneOf(Color.class)=====
RED、BLUE、

以上程式先通過noneOf()方法建立了一個只能接收Color型別的集合esetOld,然後向其增加了兩個元素;

然後,再以esetOld的集合為參考建立了一個新的集合esetNew,esetNew集合中將不包含esetOld中已有的內容。

note: 向參考集合中增加元素的語句add()的位置決定了esetNew裡面的元素~~~

import java.util.EnumSet;
enum Color{
    RED, GREEN, BLUE;
}

public class EnumSetDemo04_03{
    public static void main(String args[]){
        EnumSet<Color> esetOld = null;
        EnumSet<Color> esetNew = null;
        //System.out.println("======EnumSet.allOf(Color.class)=====");
        //eset = EnumSet.allOf(Color.class);
        //System.out.println("======EnumSet.of(Color.class)=====");
        //eset = EnumSet.of(Color.BLUE);
        esetOld = EnumSet.noneOf(Color.class); //可以加入Color型別的物件
        esetOld.add(Color.BLUE);
        
        esetNew = EnumSet.complementOf(esetOld);  //建立一個不包含指定元素的集合
        
        esetOld.add(Color.RED);
                
        System.out.println("======EnumSet.complementOf(Color.class)=====");
        print(esetNew);
        System.out.println("======EnumSet.Of(Color.class)=====");
        print(esetOld);
    }
    
    public static void print(EnumSet<Color> temp){
        for(Color c:temp){
            System.out.print(c + "、");
        }
        System.out.println();
    }
}

執行結果:

======EnumSet.complementOf(Color.class)=====
RED、GREEN、
======EnumSet.Of(Color.class)=====
RED、BLUE、

(5)範例: 驗證EnumSet -- 複製已有的內容

package org.forfan06.enumdemo;
import java.util.EnumSet;
enum Color{
    RED, GREEN, BLUE;
}

public class EnumSetDemo05{
    public static void main(String args[]){
        EnumSet<Color> esetOld = null;
        EnumSet<Color> esetNew = null;
        //System.out.println("======EnumSet.allOf(Color.class)=====");
        //eset = EnumSet.allOf(Color.class);
        //System.out.println("======EnumSet.of(Color.class)=====");
        //eset = EnumSet.of(Color.BLUE);
        esetOld = EnumSet.noneOf(Color.class); //可以加入Color型別的物件
        esetOld.add(Color.BLUE);
        esetOld.add(Color.RED);
        esetNew = EnumSet.copyOf(esetOld);  //建立一個不包含指定元素的集合
                
        System.out.println("======EnumSet.complementOf(Color.class)=====");
        print(esetNew);
        System.out.println("======EnumSet.copyOf(Color.class)=====");
        print(esetOld);
    }
    
    public static void print(EnumSet<Color> temp){
        for(Color c:temp){
            System.out.print(c + "、");
        }
        System.out.println();
    }
}

執行結果:

======EnumSet.complementOf(Color.class)=====
RED、BLUE、
======EnumSet.copyOf(Color.class)=====
RED、BLUE、

14.6 列舉類實現介面

       列舉類也可以實現一個介面,但是,因為介面中會存在抽象方法,所以列舉類中的每個物件都必須分別實現此抽象方法

範例: 列舉類實現一個介面

package org.forfan06.enumdemo;
interface Print{
    public String getColor();
}
enum Color implements Print{
    RED{
        public String getColor(){
            return "紅色";
        }
    },
    GREEN{
        public String getColor(){
            return "綠色";
        }
    },
    BLUE{
        public String getColor(){
            return "藍色";
        }
    };
}

public class EnumeImplementsInterfaceDemo{
    public static void main(String args[]){
        for(Color c:Color.values()){
            System.out.print(c.getColor() + "、");
        }
    }
}

執行結果:

紅色、綠色、藍色、

                *****列舉類在實現一個介面之後,就必須對列舉類中的每個物件分別實現介面中的抽象方法*****

14.7 列舉類定義抽象方法

          列舉類除了可以實現介面之外(每個列舉物件都必須分別實現介面中的抽象方法), 還可以在列舉類中定義抽象方法,這樣每個列舉的物件只要分別實現了抽象方法即可。

範例: 在列舉類中定義抽象方法

enum Color{
    RED{
        public String getColor(){
            return "紅色";
        }
    },
    GREEN{
        public String getColor(){
            return "綠色";
        }
    },
    BLUE{
        public String getColor(){
            return "藍色";
        }
    };
    public abstract String getColor();
}

public class AbstractEnumDemo{
    public static void main(String args[]){
        for(Color c:Color.values()){
            System.out.print(c.getColor() + "、");
        }
    }
}

執行結果:

紅色、綠色、藍色、

追問: 此時列舉類Color為什麼可以不用abstract關鍵字來修飾呢????????????? 

14.8 本章要點

  1. 在程式中可以使一個列舉來指定物件的取值範圍
  2. 在Java中使用enum關鍵字定義一個列舉類, 每個列舉類都是繼承Enum類
  3. 在列舉中可以通過values()方法取得列舉中的全部內容
  4. 在列舉類中可以定義構造方法,但是在設定列舉範圍時必須顯式地呼叫構造方法
  5. 所有的列舉類都可以直接使用Comparable進行排序,因為Enum類實現了Comparable介面
  6. Java類集中提供了列舉的支援類EnumMap、EnumSet兩個類 
  7. 一個列舉類可以實現一個介面或在類中定義抽象方法;但是,每個列舉物件都必須分別實現全部的抽象方法

14.9 習題

  1. 定義一個品牌電腦的列舉類,其中只有固定的幾個電腦品牌
  2. 定義一個Person類,其中包含姓名、年齡、生日、性別的屬性,其中性別只能是“男”或“女”

14.10 參考資料