@ 枚举类型可以将一组具有名称的值的优先级和创建为一种新的类型。我们可以像创建类一样创建枚举类型。比如
1 |
|
@ 枚举类型有几个常用的方法。
-
values(),返回该枚举类型所有的常量数组。
-
ordinal(),返回某个常量所在枚举类型的位置,从0开始。Food.ORANGE.ordinal()的值是1
-
name(),返回当前常量的名字。
-
toString(),同name()
-
equals(),比较两个枚举类型的值是否相同。由于枚举类型是单例并且是常量,所以枚举类型的比较可以直接用“==”。
-
static valueOf(Class
enumType, String name),根据枚举类型和名称找到该枚举的值。 -
compareTo(),比较两个枚举值的顺序,通过ordinal()的值做差得出结果。
-
valueOf(String name),这个方法不是静态方法,所有需要一个枚举实例来调用。
@ 枚举还有静态引用的功能,由于省略了类型名,对后期维护容易造成困惑,不推荐使用。
@ 枚举类型是常量,不可以被继承,也不能继承其他类,但是可以让枚举类型实现接口。
@ 枚举类型可以添加描述,即每个常量可以赋值,可以是基本类型,可以是类。
============
前段时间想实现国内各个省,市,区的管理功能,这在购物网站填写地址时会用到。我想了几种实现方法,比如:
方法一:省,市,区均设定为model,在数据库里分别创建表,写实际的中文名称,比如“北京”,“大连”等等。这种表示方式好处是简洁明了,缺点是每个地址都需要存储汉字,导致数据库内容重复。
方法二:省,市,区均设定model,在数据库里创建表,用键值对的形式表示地点。比如省份使用两位int的值表示,“10” - 北京,“12” - “辽宁”;四位表示市,“1212” - (辽宁)大连,前两位表示省份,后两位是市;六位表示市区,“121210” - (辽宁大连)甘井子。这种表示方式的好处是可以只通过市区就定位该市区具体行政关系。缺点是省和市的内容重复。
方法三:省,市,区均用int表示,显示的写在java代码里,并用map关联。这种方式的好处是不占用数据库资源,在数据库里只需要给出三个列表示省市区即可。缺点是int值很容易重复,表明意义不清晰,如果使用“101112”的形式表示则增加了数据位数,也显得冗余。
方法四:使用枚举表示省,市,区。这种方式好处是不占用数据库,常量的值不会被更改,表达意义清晰。缺点是设计和实现稍微复杂。
我尝试的用枚举构思并实现了一下,仅供参考。1.0版本的代码可以参考https://github.com/bejondshao/personal/commit/ed3fe52f99e6bf0f7156befd9443eda12f275714
- 从区入手,设计District接口,这个接口里显示的声明多个以城市为组,将区分组。
1 |
|
由于枚举可以实现接口,所以声明的"Beijing", "Dalian"都是接口,虽然是市名,但这个类型其实是表达这个市所包含的市区,所以类型是“区”
- 设计市。以辽宁省的市为例,将辽宁省所包含的市设为常量。
1 |
|
本来想声明市也是个接口,这样可以和区一样设计并管理,但是由于市和区要进行关联,关联的过程需要有构造函数,而接口不允许有构造函数。并且我们需要在市的层级上添加方法,获取该市的区,所以无法通过继承接口实现。
构造函数
1 | LiaoningCity(Class<? extends District> district) |
有两个功能,一是将特定的市的区赋值给不同的市,二是初始化districts,这个变量可以返回某个市的所有区,而不是辽宁省的所有市的所有区。
- 设计省,设计方式和市一样,这个类型就是辽宁省,所以只有一个常量,将LiaoningCity赋给它。
1 |
|
以上就是设计区,市,省的过程,测试方法
1 |
|
getDistrictsByCityName() 的运行结果:
1 |
|
getDistrictsByProvinceName() 的运行结果:
1 |
|
所以我们可以根据“省份”下拉框来动态生成“市”的下拉框,接着“市区”下拉框。