導航:首頁 > 編程語言 > java枚舉被繼承嗎

java枚舉被繼承嗎

發布時間:2022-04-26 11:19:48

A. 關於java枚舉的疑惑

首先Enumeration是一個介面,不是類,你想使用,就做個類實現它。
java.util.Enumeration
不過它其實不是傳統意義上的枚舉類型,他是用來訪問某些集合類的介面,類似Iterator
散列與向量用Enumration,鏈表與樹集用Iteration

TestEnum和Enum沒有關系,枚舉是不能繼承一個類或其他枚舉的。只能實現介面。你能使用values是因為你聲明TestEnum是enum,不是因為TestEnum繼承自誰。你是不是認為你沒寫values,還能使values,是因為TestEnum繼承自某一個類似於object的公共基類?不是這樣。

values方法是你指定Enum這種類型後,編譯器為你實現的。

另外,使用java,最好不要使用枚舉。那是面向過程編程遺留的數據類型。其實並不符合oop思想。完全可以用類來代替它。

B. java枚舉類型

java 枚舉類型enum 的使用
最近跟同事討論問題的時候,突然同事提到我們為什麼java 中定義的常量值不採用enmu 枚舉類型,而採用public final static 類型來定義呢?以前我們都是採用這種方式定義的,很少採用enum 定義,所以也都沒有注意過,面對突入起來的問題,還真有點不太清楚為什麼有這樣的定義。既然不明白就抽時間研究下吧。
Java 中的枚舉類型採用關鍵字enum 來定義,從jdk1.5才有的新類型,所有的枚舉類型都是繼承自Enum 類型。要了解枚舉類型,建議大家先打開jdk 中的Enum類簡單讀一下,這個類裡面定義了很多protected 方法,比如構造函數,如果要使用這些方法我們可以把枚舉類型定義到當前類中。每個枚舉類型,都有自己的名字和順序,當我們輸出一個枚舉類型的時候,會輸入枚舉類型的name ,具體可以參考下面的例子。
一、 通常定義常量方法
我們通常利用public final static 方法定義的代碼如下,分別用1 表示紅燈,3 表示綠燈,2 表示黃燈。

package com.csdn.myEnum;
public class Light {
/* 紅燈 */
public final static int RED =1;
/* 綠燈 */
public final static int GREEN =3;
/* 黃燈 */
public final static int YELLOW =2;
}

二、 枚舉類型定義常量方法
枚舉類型的簡單定義方法如下,我們似乎沒辦法定義每個枚舉類型的值。比如我們定義紅燈、綠燈和黃燈的代碼可能如下:

public enum Light {
RED , GREEN , YELLOW ;
}

我們只能夠表示出紅燈、綠燈和黃燈,但是具體的值我們沒辦法表示出來。別急,既然枚舉類型提供了構造函數,我們可以通過構造函數和覆寫toString方法來實現。首先給Light 枚舉類型增加構造方法,然後每個枚舉類型的值通過構造函數傳入對應的參數,同時覆寫toString 方法,在該方法中返回從構造函數中傳入的參數,改造後的代碼如下:

public enum Light {
// 利用構造函數傳參
RED (1), GREEN (3), YELLOW (2);

// 定義私有變數
private int nCode ;

// 構造函數,枚舉類型只能為私有
private Light( int _nCode) {
this . nCode = _nCode;
}

@Override
public String toString() {
return String.valueOf ( this . nCode );
}
}

三、 完整示例代碼
枚舉類型的完整演示代碼如下:

package com.csdn.myEnum;

import java.util.EnumMap;
import java.util.EnumSet;

public class LightTest {

// 1. 定義枚舉類型
public enum Light {
// 利用構造函數傳參
RED (1), GREEN (3), YELLOW (2);

// 定義私有變數
private int nCode ;

// 構造函數,枚舉類型只能為私有
private Light( int _nCode) {
this . nCode = _nCode;
}

@Override
public String toString() {
return String.valueOf ( this . nCode );
}
}

/**
* @param args
*/
public static void main(String[] args ) {

// 1. 遍歷枚舉類型
System. out .println( " 演示枚舉類型的遍歷 ......" );
testTraversalEnum ();

// 2. 演示 EnumMap 對象的使用
System. out .println( " 演示 EnmuMap 對象的使用和遍歷 ....." );
testEnumMap ();

// 3. 演示 EnmuSet 的使用
System. out .println( " 演示 EnmuSet 對象的使用和遍歷 ....." );
testEnumSet ();
}

/**
* 演示枚舉類型的遍歷
*/
private static void testTraversalEnum() {
Light[] allLight = Light.values ();
for (Light aLight : allLight) {
System. out .println( " 當前燈 name : " + aLight.name());
System. out .println( " 當前燈 ordinal : " + aLight.ordinal());
System. out .println( " 當前燈: " + aLight);
}
}

/**
* 演示 EnumMap 的使用, EnumMap 跟 HashMap 的使用差不多,只不過 key 要是枚舉類型
*/
private static void testEnumMap() {
// 1. 演示定義 EnumMap 對象, EnumMap 對象的構造函數需要參數傳入 , 默認是key 的類的類型
EnumMap<Light, String> currEnumMap = new EnumMap<Light, String>(
Light. class );
currEnumMap.put(Light. RED , " 紅燈 " );
currEnumMap.put(Light. GREEN , " 綠燈 " );
currEnumMap.put(Light. YELLOW , " 黃燈 " );

// 2. 遍歷對象
for (Light aLight : Light.values ()) {
System. out .println( "[key=" + aLight.name() + ",value="
+ currEnumMap.get(aLight) + "]" );
}
}

/**
* 演示 EnumSet 如何使用, EnumSet 是一個抽象類,獲取一個類型的枚舉類型內容<BR/>
* 可以使用 allOf 方法
*/
private static void testEnumSet() {
EnumSet<Light> currEnumSet = EnumSet.allOf (Light. class );
for (Light aLightSetElement : currEnumSet) {
System. out .println( " 當前 EnumSet 中數據為: " + aLightSetElement);
}

}
}

執行結果如下:

演示枚舉類型的遍歷 ......
當前燈 name : RED
當前燈 ordinal : 0
當前燈: 1
當前燈 name : GREEN
當前燈 ordinal : 1
當前燈: 3
當前燈 name : YELLOW
當前燈 ordinal : 2
當前燈: 2
演示 EnmuMap 對象的使用和遍歷 .....
[key=RED,value= 紅燈 ]
[key=GREEN,value= 綠燈 ]
[key=YELLOW,value= 黃燈 ]
演示 EnmuSet 對象的使用和遍歷 .....
當前 EnumSet 中數據為: 1
當前 EnumSet 中數據為: 3
當前 EnumSet 中數據為: 2

四、 通常定義常量方法和枚舉定義常量方法區別
以下內容可能有些無聊,但絕對值得一窺
1. 代碼:
public class State {
public static final int ON = 1;
public static final Int OFF= 0;
}

有什麼不好了,大家都這樣用了很長時間了,沒什麼問題啊。
首先,它不是類型安全的。你必須確保是int
其次,你還要確保它的范圍是0 和1
最後,很多時候你列印出來的時候,你只看到 1 和0 ,

但其沒有看到代碼的人並不知道你的企圖,拋棄你所有舊的public static final 常量
2. 可以創建一個enum 類,把它看做一個普通的類。除了它不能繼承其他類了。(java 是單繼承,它已經繼承了Enum),
可以添加其他方法,覆蓋它本身的方法
3. switch() 參數可以使用enum 了
4. values() 方法是編譯器插入到enum 定義中的static 方法,所以,當你將enum 實例向上轉型為父類Enum 是,values() 就不可訪問了。解決辦法:在Class中有一個getEnumConstants() 方法,所以即便Enum 介面中沒有values() 方法,我們仍然可以通過Class 對象取得所有的enum 實例
5. 無法從enum 繼承子類,如果需要擴展enum 中的元素,在一個介面的內部,創建實現該介面的枚舉,以此將元素進行分組。達到將枚舉元素進行分組。
6. 使用EnumSet 代替標志。enum 要求其成員都是唯一的,但是enum 中不能刪除添加元素。
7. EnumMap 的key 是enum ,value 是任何其他Object 對象。
8. enum 允許程序員為eunm 實例編寫方法。所以可以為每個enum 實例賦予各自不同的行為。
9. 使用enum 的職責鏈(Chain of Responsibility) . 這個關繫到設計模式的職責鏈模式。以多種不同的方法來解決一個問題。然後將他們鏈接在一起。當一個請求到來時,遍歷這個鏈,直到鏈中的某個解決方案能夠處理該請求。
10. 使用enum 的狀態機
11. 使用enum 多路分發

C. java,求高手講解一下一個枚舉的例子

結果:Mr. John Doe
轉的。枚舉是一個特殊的類。

枚舉類型是JDK5.0的新特徵 。Sun引進了一個全新的關鍵字enum來定義一個枚舉類 。下面就是一個典型枚舉類型的定義:

Java代碼:

public enum Color{
RED,BLUE,BLACK,YELLOW,GREEN
}

顯然,enum很像特殊的class,實際上enum聲明定義的類型就是一個類 。 而這些類都是類庫中Enum類的子類(java.lang.Enum) 。它們繼承了這個Enum中的許多有用的方法 。我們對代碼編譯之後發現,編譯器將enum類型單獨編譯成了一個位元組碼文件:Color.class 。

Color位元組碼代碼

final enum hr.test.Color {
// 所有的枚舉值都是類靜態常量
public static final enum hr.test.Color RED;
public static final enum hr.test.Color BLUE;
public static final enum hr.test.Color BLACK;
public static final enum hr.test.Color YELLOW;
public static final enum hr.test.Color GREEN;
private static final synthetic hr.test.Color〔〕 ENUM$VALUES;
// 初始化過程,對枚舉類的所有枚舉值對象進行第一次初始化
static {
0 new hr.test.Color 〔1〕
3 p
4 ldc 〔16〕 //把枚舉值字元串「RED」壓入操作數棧
6 iconst_0 // 把整型值0壓入操作數棧
7 invokespecial hr.test.Color(java.lang.String, int) 〔17〕 //調用Color類的私有構造器創建Color對象RED
10 putstatic hr.test.Color.RED : hr.test.Color 〔21〕 //將枚舉對象賦給Color的靜態常量RED 。
。.. 。.. 。.. 枚舉對象BLUE等與上同
102 return
};
// 私有構造器,外部不可能動態創建一個枚舉類對象(也就是不可能動態創建一個枚舉值) 。
private Color(java.lang.String arg0, int arg1){
// 調用父類Enum的受保護構造器創建一個枚舉對象
3 invokespecial java.lang.Enum(java.lang.String, int) 〔38〕
};
public static hr.test.Color〔〕 values();
// 實現Enum類的抽象方法
public static hr.test.Color valueOf(java.lang.String arg0);
}

下面我們就詳細介紹enum定義的枚舉類的特徵及其用法 。(後面均用Color舉例)

1、Color枚舉類就是class,而且是一個不可以被繼承的final類 。

其枚舉值(RED,BLUE. 。.)都是Color類型的類靜態常量, 我們可以通過下面的方式來得到Color枚舉類的一個實例:

Color c=Color.RED;

注意:這些枚舉值都是public static final的,也就是我們經常所定義的常量方式,因此枚舉類中的枚舉值最好全部大寫 。

2、即然枚舉類是class,當然在枚舉類型中有構造器,方法和數據域 。

但是,枚舉類的構造器有很大的不同:

(1) 構造器只是在構造枚舉值的時候被調用 。

Java代碼:

enum Color{
RED(255,0,0),BLUE(0,0,255),BLACK(0,0,0),YELLOW(255,255,0),GREEN(0,255,0);
//構造枚舉值,比如RED(255,0,0)
private Color(int rv,int gv,int bv){
this.redValue=rv;
this.greenValue=gv;
this.blueValue=bv;
}
public String toString(){ //覆蓋了父類Enum的toString()
return super.toString()+「(」+redValue+「,」+greenValue+「,」+blueValue+「)」;
}
private int redValue; //自定義數據域,private為了封裝 。
private int greenValue;
private int blueValue;
}

(2) 構造器只能私有private,絕對不允許有public構造器 。 這樣可以保證外部代碼無法新構造枚舉類的實例 。這也是完全符合情理的,因為我們知道枚舉值是public static final的常量而已 。 但枚舉類的方法和數據域可以允許外部訪問 。

Java代碼:

public static void main(String args〔〕)
{
// Color colors=new Color(100,200,300); //wrong
Color color=Color.RED;
System.out.println(color); // 調用了toString()方法
}

3、所有枚舉類都繼承了Enum的方法,下面我們詳細介紹這些方法 。

(1) ordinal()方法: 返回枚舉值在枚舉類種的順序 。這個順序根據枚舉值聲明的順序而定 。

Color.RED.ordinal(); //返回結果:0
Color.BLUE.ordinal(); //返回結果:1

(2) compareTo()方法: Enum實現了java.lang.Comparable介面,因此可以比較象與指定對象的順序 。Enum中的compareTo返回的是兩個枚舉值的順序之差 。當然,前提是兩個枚舉值必須屬於同一個枚舉類,否則會拋出ClassCastException()異常 。(具體可見源代碼)

Color.RED.compareTo(Color.BLUE); //返回結果 -1

(3) values()方法: 靜態方法,返回一個包含全部枚舉值的數組 。

Color〔〕 colors=Color.values();
for(Color c:colors){
System.out.print(c+「,」);
}//返回結果:RED,BLUE,BLACK YELLOW,GREEN,

(4) toString()方法: 返回枚舉常量的名稱 。

Color c=Color.RED;
System.out.println(c);//返回結果: RED

(5) valueOf()方法: 這個方法和toString方法是相對應的,返回帶指定名稱的指定枚舉類型的枚舉常量 。

Color.valueOf(「BLUE」); //返回結果: Color.BLUE

(6) equals()方法: 比較兩個枚舉類對象的引用 。

Java代碼:

//JDK源代碼:
public final boolean equals(Object other) {
return this==other;
}

4、枚舉類可以在switch語句中使用 。

Java代碼:

Color color=Color.RED;
switch(color){
case RED: System.out.println(「it『s red」);break;
case BLUE: System.out.println(「it』s blue」);break;
case BLACK: System.out.println(「it『s blue」);break;
}

D. java枚舉方面的問題,見問題補充

<E extends Enum<E>>代表類型的限定聲明,限定了E只能是Enum<E>的子類,即只能繼承自「枚舉類」。
EnumSet<E>代表返回值的類型,復制並返回另一個EnumSet枚舉數集。

import java.util.Arrays;
import java.util.EnumSet;

public class Test {
static enum 果{ 蘋果,梨,葡萄}
static public void main(String 參數[]){
果 a[]={ 果.梨, 果.蘋果};
EnumSet<果> s1,s2;
s1=EnumSet.Of(Arrays.asList(a));
s2=EnumSet.Of(Arrays.asList(果.values()));
System.out.println(s1);
System.out.println(s2);
}
}
=======
[蘋果, 梨]
[蘋果, 梨, 葡萄]

E. java枚舉的幾種用法

用法一:常量
在JDK1.5 之前,我們定義常量都是: public static fianl.... 。現在好了,
有了枚舉,可以把相關的常量分組到一個枚舉類型里,而且枚舉提供了比常量更多的方法。
Java代碼

public enum Color {
RED, GREEN, BLANK, YELLOW
}

用法二:switch
JDK1.6之前的switch語句只支持int,char,enum類型,使用枚舉,能讓我們的代碼可讀性更強。
Java代碼

enum Signal {
GREEN, YELLOW, RED
}
public class TrafficLight {
Signal color = Signal.RED;
public void change() {
switch (color) {
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break;
}
}
}

用法三:向枚舉中添加新方法
如果打算自定義自己的方法,那麼必須在enum實例序列的最後添加一個分號。而且 Java 要求必須先定義 enum 實例。
Java代碼
public enum Color {
RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);
// 成員變數
private String name;
private int index;
// 構造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
// 普通方法
public static String getName(int index) {
for (Color c : Color.values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
}
// get set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}

用法四:覆蓋枚舉的方法
下面給出一個toString()方法覆蓋的例子。
Java代碼

public enum Color {
RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);
// 成員變數
private String name;
private int index;
// 構造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
//覆蓋方法
@Override
public String toString() {
return this.index+"_"+this.name;
}
}

用法五:實現介面
所有的枚舉都繼承自java.lang.Enum類。由於Java 不支持多繼承,所以枚舉對象不能再繼承其他類。
Java代碼

public interface Behaviour {
void print();
String getInfo();
}
public enum Color implements Behaviour{
RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);
// 成員變數
private String name;
private int index;
// 構造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
//介面方法
@Override
public String getInfo() {
return this.name;
}
//介面方法
@Override
public void print() {
System.out.println(this.index+":"+this.name);
}
}

用法六:使用介面組織枚舉
Java代碼

public interface Food {
enum Coffee implements Food{
BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO
}
enum Dessert implements Food{
FRUIT, CAKE, GELATO
}
}

private static void testImplementsInterface() {
for (Food.DessertEnum dessertEnum : Food.DessertEnum.values()) {
System.out.print(dessertEnum + " ");
}
System.out.println();
//我這地方這么寫,是因為我在自己測試的時候,把這個coffee單獨到一個文件去實現那個food介面,而不是在那個介面的內部。
for (CoffeeEnum coffee : CoffeeEnum.values()) {
System.out.print(coffee + " ");
}
System.out.println();
//搞個實現介面,來組織枚舉,簡單講,就是分類吧。如果大量使用枚舉的話,這么干,在寫代碼的時候,就很方便調用啦。
//還有就是個「多態」的功能吧,
Food food = Food.DessertEnum.CAKE;
System.out.println(food);
food = CoffeeEnum.BLACK_COFFEE;
System.out.println(food);
}

F. java 可以 繼承的枚舉 怎麼寫

importjava.util.ArrayList;
importjava.util.List;

publicclassColor{
privateStringvalue;
privatestaticList<Color>colors=newArrayList<Color>();
publicColor(Stringvalue){
this.value=value;
colors.add(this);
}
publicstaticColorRed=newColor("red");
publicstaticColorBlud=newColor("Blud");
publicstaticColorGreen=newColor("Green");

publicvoidtest(){
System.out.println("我是"+value);
}

publicstaticColor[]values(){
returncolors.toArray(newColor[colors.size()]);
}

publicstaticvoidmain(String[]args){
Color.Red.test();
Color.Green.test();
ColorB.black.test();

for(Colorc:ColorB.values()){
c.test();
}
}

}

/**
*子類
*@author儲寶
*
*/
classColorBextendsColor{
publicColorB(Stringvalue){
super(value);
}

publicstaticColorBblack=newColorB("black");

}

枚舉的偽實現。和枚舉不同的是,還是可以new一個對象,本來是想把構造私有化的,但是就不能繼承了。

閱讀全文

與java枚舉被繼承嗎相關的資料

熱點內容
銀河麒麟字體庫存在哪個文件夾 瀏覽:956
魔獸加丁伺服器的航空叫什麼 瀏覽:152
花冠改裝案例哪個app多 瀏覽:515
成績單app哪個好用 瀏覽:140
北美程序員vs國內程序員 瀏覽:181
php解析xml文檔 瀏覽:121
石墨文檔APP怎麼橫屏 瀏覽:185
牆主鋼筋加密和非加密怎麼看 瀏覽:144
金山區文件夾封套定製 瀏覽:708
soho程序員 瀏覽:672
java位元組截取 瀏覽:525
php提交作業 瀏覽:815
房產還沒解壓可以辦理贈予嗎 瀏覽:224
java毫秒轉分鍾 瀏覽:753
模式識別中文pdf 瀏覽:774
c語言平均數字編譯錯誤 瀏覽:171
單片機算交流 瀏覽:45
php自適應網站 瀏覽:467
2b2t伺服器怎麼獲得許可權 瀏覽:816
c語言javaphp 瀏覽:804