为什么要使用枚举,枚举为何被称为语法糖?

为什么要用枚举呢?


     在JDK1.5之前,Java有两种方式定义新类型:类和接口。对于大部分面向对象编程来说,这两种方法看起来似乎足够了。但是在一些特殊情况下,这些方法就不适合。例如,想定义一个Color类,它只能有RED、GREEN、BLUE 3种值,其他的任何值都是非法的,那么JDK1.5之前虽然可以构造这样的代码,但是要做很多的工作,就可能带来很多不安全的问题。而JDK1.5之后引入的枚举类型就能解决这些问题。


什么是枚举呢?

    枚举,在数学上是指有穷序列集,就是说某一类东西,能一一列出来。比如月份,可以有一月、二月......十二月,不能再多了,星期也是一样的概念。先声明,如果只是简单的穷举,除了语义更明确,我没觉得用“枚举”来替代“一个接口定义几个常量”这种方式有什么其他优势,只有被穷举的对象有一定业务性导致其具有一定复杂性,枚举才体现其简约。

    枚举还有一个特点,就是可以代表数值,比如说第一个定义的元素对应的值为0,每个枚举元素从0开始,逐一增加。此时,这个数值也代表他们本身,相当于每一个元素有两个名字。

 


什么时候使用呢

1、一周有多少天?

    7天。像这样固定不变的一组数据,如果我们的程序有需要用到这“7天”的相关信息,例如:发工资分为工作日和周末,可以考虑使用枚举类型。

2、太阳系有多少个行星?

    8个。当我们需要计算每个行星的表面重力的时候,像这样我们需要用到固定不变的一组信息中的每一个元素携带了不同的信息,可以考虑使用枚举类型。 

3、计算器中的基础运算符。

     加减乘除。像这样我们需要用到固定不变的一组信息中的每一个元素都决定了不同的行为的时候,可以考虑使用枚举类型。

4、web请求返回的状态。

    比如:error为-1,success为0,未登录为-9等可以设为枚举类型。

 


为什么说枚举是语法糖呢?

 

假如我们要定义季节类,包含一个季节名称和执行计划,没有枚举之前我们也许是这样做的

 

定义一个父类


public abstract class Weather {
   
	public String name;
	abstract void  plan();
}

定义春天

public class SpringWeather extends Weather{
	
	public SpringWeather(String name) {
		this.name=name;
	}

	@Override
	void plan() {
		System.out.println("春天");
	}

}

定义夏天

public class SummerWeather extends Weather{
	
	public SummerWeather(String name) {
		this.name=name;
	}

	@Override
	void plan() {
		System.out.println("夏天");
	}

}

定义秋天,定义冬天....... 

 

      如上加上我们省略掉的,要穷举季节这样一个具有一定复杂性的有穷序列集,我们要写多个类,JAVA语法真啰嗦!有了枚举之后我们可以这样写:

public enum WeatherEnum {

	SPRING(1, "春天") {
		@Override
		void plan() {
			System.out.println("春天");
		}
	},
	SUMMER(2, "夏天") {
		@Override
		void plan() {
			System.out.println("夏天");
		}
	},
	AUTUMN(3, "秋天") {
		@Override
		void plan() {
			System.out.println("秋天");
		}
	},
	WINTER(4, "冬天") {
		@Override
		void plan() {
			System.out.println("冬天");
		}
	};

	private Integer num;

	private String name;

	private WeatherEnum(Integer num, String name) {
		this.num = num;
		this.name = name;
	}

	public Integer getNum() {
		return num;
	}

	public void setNum(Integer num) {
		this.num = num;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	abstract void plan();

	@Override
	public String toString() {
		return "num:" + this.num + "  name:" + this.name;
	}
}

     只需要enum关键字定义一个类就可以代替上面的多个类,确实简约!

     事实上现实中的业务比季节这个概念要复杂些,没有枚举的话可能还需要更多的类定义,比如季节里面的计划,我们现在仅仅是简单地输出一句话而已。
      以上便是JAVA枚举语法糖的一个优势,既然是语法糖,也就是说,只是看起来是这样子,事实上枚举定义编译后,也是被编译成了多个class。这个可以查看编译后的class文件就知道了!

      可以看出,使用枚举能使我们减少类的定义,并且语义明确,使用面向对象的说法就是枚举实现了代码复用。

     再查看一下反编译后的类,发现类都是被static修饰的,当我们使用enmu来定义一个枚举类型的时候,编译器会自动帮我们创建一个final类型的类,所以枚举类型不能被继承.


参考:https://www.jianshu.com/p/3f3a7de11812

以下是一个基于栈的出栈序列检查的C语言代码: ```c #include <stdio.h> #include <stdlib.h> #define MAX_STACK_SIZE 100 int stack[MAX_STACK_SIZE]; int top = -1; void push(int val) { if (top == MAX_STACK_SIZE - 1) { printf("Stack overflow\n"); exit(1); } stack[++top] = val; } int pop() { if (top == -1) { printf("Stack underflow\n"); exit(1); } return stack[top--]; } int main() { int n, i, j; int push_seq[MAX_STACK_SIZE], pop_seq[MAX_STACK_SIZE]; printf("Enter the size of the sequence: "); scanf("%d", &n); printf("Enter the push sequence: "); for (i = 0; i < n; i++) { scanf("%d", &push_seq[i]); } printf("Enter the pop sequence: "); for (i = 0; i < n; i++) { scanf("%d", &pop_seq[i]); } i = 0; j = 0; while (i < n && j < n) { if (push_seq[i] == pop_seq[j]) { i++; j++; } else if (top != -1 && stack[top] == pop_seq[j]) { pop(); j++; } else { push(push_seq[i++]); } } while (top != -1 && j < n) { if (stack[top] == pop_seq[j]) { pop(); j++; } else { break; } } if (top == -1 && j == n) { printf("The pop sequence is valid.\n"); } else { printf("The pop sequence is not valid.\n"); } return 0; } ``` 该程序要求用户输入一个序列的大小,一个压栈序列和一个出栈序列。然后,程序使用一个基于栈的算法来检查出栈序列的合法性。如果出栈序列是合法的,程序将输出“ The pop sequence is valid.”,否则输出“The pop sequence is not valid.”。 该算法的基本思想是模拟压栈和出栈过程。我们从压栈序列的开头开始遍历,遇到一个和出栈序列的当前元素相等的元素时,我们将它出栈。否则,我们将该元素压入栈中。如果栈顶元素和出栈序列的当前元素相等,则将栈顶元素出栈。 在遍历完压栈序列后,我们检查栈中剩余的元素是否可以与出栈序列中的元素匹配。如果可以,则弹出栈顶元素并移动到下一个出栈元素。如果不能匹配,则出栈序列无效。 此算法的时间复杂度为O(n),其中n为序列的大小。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值