你用過枚舉麼----枚舉成神之路

爲何用枚舉

小明同學第一次學習枚舉,老師的例子是一週的每個星期,一年的每個月份,然後他懂了,對於範圍、類別等,可以列舉出來的變量,可以使用枚舉類型。後來他發現,用1/2/3…7代替一週的7天也行啊,不一定要枚舉,結果老師給他一個參數8,他忽然明白了,用枚舉限定了輸入範圍,不需要添加判斷,同時如果對於星期一,用1表示的話,可能過幾天再看我都不知道一代表啥,但如果用Week.MONDAY,很明白代表星期一,於是,小明開始了枚舉之路。

name()方法獲取枚舉字符串值

public enum FriendType {
    GOOD, BAD
}

然後調用的時候:

public Friend addFriend(String name, boolean isgood) {
        if (isgood) {
            return new Friend(name, FriendType.GOOD);
        } else {
            return new Friend(name, FriendType.BAD);
        }
    }

心裏美滋滋,直到有一天交作業如下

public String getNameByType(FriendType type) {
        if (FriendType.GOOD == type) {
            return "GOOD";
        } else {
            return "BAD";
        }
    }

老師瘋了,你爲何如此get,不知道name()(返回name,比如FriendType.GOOD.name()爲GOOD),於是有了如下的版本:

public String getNameByType(FriendType type) {
        return type.name();
    }

ordinal()方法獲取從0開始的序號

改好之後,小明又覺得自己行了,直到有一天交作業

public int getOrderByType(FriendType type) {
        if (type == FriendType.GOOD) {
            return 0;
        } else {
            return 1;
        }
    }

老師又瘋了,你不知ordinal()(返回從0開始的序號)麼,於是小明有了如下版本

public int getOrderByType(FriendType type) {
        return type.ordinal();
    }

valueOf(String name)根據字符串值獲取枚舉實例

小明心裏不服,還能有啥啊,直到一天:

public FriendType getType(String type) {
        if (type.equals("GOOD")) {
            return FriendType.GOOD;
        }
        return FriendType.BAD;
    }

老師又瘋了,你不知道**valueOf()(更具name返回枚舉常量,比如根據"GOOD"返回FriendType.GOOD)**麼,於是乎小明改了代碼

public FriendType getType(String type) {
        return FriendType.valueOf(type);
    }

values()返回枚舉實例的數組

枚舉的屬性和方法

老師很生氣說:你太笨了,枚舉用不明白,但爲師不忍看你如此無知,再傳授你幾招吧,你說說,枚舉的本質是神馬啊?

小明:這個我知道,是class

老師吃驚,這傢伙居然知道:那如果是類的話,我想定義屬性和方法怎麼定義啊?

小明:額,還可以這樣麼(黑人問號???)

老師說:小樣,功力欠缺,爲師讓你看看。

public enum FriendType {
    GOOD("成績好"), BAD("成績壞");

    private String reason;

    private FriendType(String reason) {
        this.reason = reason;
    }

    public String getReason() {
        return reason;
    }

    public String getReasonByStrType(String type) {
        for (FriendType ft : FriendType.values()) {
            if (ft.name().equals(type)) {
                return ft.getReason();
            }
        }
        return null;
    }
}

老師說,小明啊,這下你開開眼吧

小明吃驚啊,琢磨了一會兒說,老師很厲害,但我看明白了,構造方法是私有的,因此無法在外部再增加枚舉類型的實例,有參構造函數可以使得每個實例對變量賦值,同時values()可以將枚舉常量以數組形式返回,我也會了,老師你還有別的招麼?再教我一下。

枚舉實現接口

老師看小明想學,說:好,我再給你放個大

// 該接口表示你的兩類盆友都如何對待學習的
public interface IStudy {
    //該接口有一個方法,即howToStudy(如何學習)
    public abstract void howToStudy();
}
public enum FriendType implements IStudy{
    GOOD{
        @Override
        public void howToStudy() {
            System.out.println("study hard");
        }
    },
    BAD{
        @Override
        public void howToStudy() {
            System.out.println("study not hard");
        }
    }
}

枚舉實現接口,可以在公共區域實現,也可以在內部實現,調用的話:FriendType.GOOD.howToStudy().

小明甚是驚喜,沒想到還能這麼實現接口,漲了見識

枚舉定義抽象方法

小明說:老師,其實不一定實現接口,直接把抽象方法寫在本類中,在每個枚舉實例中進行實現可以麼,於是有了另一個版本


public enum FriendType {
    GOOD{
        @Override
        public void howToStudy() {
            System.out.println("study hard");
        }
    },
    BAD{
        @Override
        public void howToStudy() {
            System.out.println("study not hard");
        }
    };

    public abstract void howToStudy();
}

枚舉的優雅使用代替if/else

小明說:老師,我發現這種方式可以有效的解決我的好多if/else,着實優雅不少啊,你看我這麼實現,本來6行代碼可以用1行搞定

public void friendStudy(String typeName) {
        // if (typeName == "GOOD") {
        //     FriendType.GOOD.howToStudy();
        // }
        // else {
        //     FriendType.BAD.howToStudy();
        // }
        FriendType.valueOf(typeName).howToStudy();
    }

小明對老師非常敬佩,老師也發現小明舉一反三很聰明。小明終於學完要走了,老師交代:設計模式中的單例可以用枚舉實現,你會麼?

枚舉的單例實現

小明說:我寫給你看下。


public enum Singleton {
    INSTANCE;
    
    public Singleton getInstance() {
        return INSTANCE;
    }
    
    public void doSomeThing() {
        System.out.println("doSomeThing");
    }
}

就這樣,小明順利學完枚舉,成爲枚舉大神~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章