枚举对象是枚举类型的数据对象。枚举对象只能包含类型为枚举类型的枚举值。ABAP从版本7.51开始支持它们。

这是一种常见的模式。在ABAP 7.51之前,人们通常用如下方式实现类似的功能:

CLASS cx_wrong_size DEFINITION INHERITING FROM cx_static_check.
ENDCLASS. CLASS shirt DEFINITION.
PUBLIC SECTION.
TYPES tsize TYPE i.
CONSTANTS:
size_s TYPE tsize VALUE ,
size_m TYPE tsize VALUE ,
size_l TYPE tsize VALUE ,
size_xl TYPE tsize VALUE .
METHODS
constructor IMPORTING size TYPE tsize
RAISING cx_wrong_size.
...
PRIVATE SECTION.
DATA
size TYPE tsize.
ENDCLASS. CLASS shirt IMPLEMENTATION.
METHOD constructor.
IF size <> size_s AND
size <> size_m AND
size <> size_l AND
size <> size_xl.
RAISE EXCEPTION TYPE cx_wrong_size.
ENDIF.
me->size = COND #(
WHEN size <> size_s AND
size <> size_m AND
size <> size_l AND
size <> size_xl THEN THROW cx_wrong_size( )
ELSE size ).
ENDMETHOD.
ENDCLASS.

这里,size属性只可以是shirt类中定义的常量中的值。其它值会导致异常。用户创建shirt类时,需要这样做:

TRY.
DATA(shirt) = NEW shirt( shirt=>size_xl ).
CATCH cx_wrong_size.
...
ENDTRY.

看到开销了吗?为什么不让运行时环境来为你做值检查呢?有一种叫做枚举和枚举类型的概念(可以在这种情况下应用)。

在7.51以及更高的版本里,ABAP也会支持枚举概念。如果使用枚举类型来重写上面的例子的话:

CLASS shirt DEFINITION.
PUBLIC SECTION.
TYPES:
BEGIN OF ENUM tsize,
size_s,
size_m,
size_l,
size_xl,
END OF ENUM tsize.
METHODS
constructor IMPORTING size TYPE tsize.
...
PRIVATE SECTION.
DATA
size TYPE tsize.
ENDCLASS. CLASS shirt IMPLEMENTATION.
METHOD constructor.
me->size = size.
ENDMETHOD.
ENDCLASS.

TYPES语句的一个新变式:BEGIN OF ENUMEND OF ENUM,它可以围起一个常量的集。常量的标准基本类型是i并且枚举值从0开始计数。

像上文那样使用的话:

DATA(shirt) = NEW shirt( shirt=>size_xl ).

不过,使用了枚举对象后,你不再需要处理异常了。如果你传递一个非法值的话,会得到语法错误!

DATA(shirt) = NEW shirt(  ).

枚举是类型和常量的混合体。通过BEGIN OF ENUM enum – END OF ENUM enum 你声明了一个可以在TYPE附加项后声明的基本类型enum。在它们之间,你可以声明一个常量集,它们叫做枚举常量。这样就定义了拥有enum类型的枚举对象所允许的枚举值。在这里,TYPES实际上就和CONSTANTS语句一样。

ABAP运行时环境会检查只有被允许的枚举值可以被赋给枚举对象。

TYPES:
BEGIN OF ENUM tsize,
size_s,
size_m,
size_l,
size_xl,
END OF ENUM tsize. DATA size TYPE tsize.
size = size_xl. "允许 DATA dobj LIKE size.
dobj = size. "允许 dobj = . "语法或运行时错误

枚举对象只能赋值给拥有相同枚举类型的枚举对象。同样,枚举对象间的比较也只能在相同类型的枚举对象间发生。当然,枚举常量本身也包含在内。

通常,你一点也不关心枚举对象的内容。枚举对象的语义由枚举常量来定义。然而,你也可以将枚举类型定义为i类型之外的其它基本类型,并且拥有其它枚举值(其中一个必须是初始值):

TYPES:
basetype TYPE c LENGTH ,
BEGIN OF ENUM tsize BASE TYPE basetype,
size_i VALUE IS INITIAL,
size_s VALUE `S`,
size_m VALUE `M`,
size_l VALUE `L`,
size_xl VALUE `XL`,
END OF ENUM tsize. DATA size TYPE tsize.
size = size_xl. "允许 DATA dobj LIKE size.
dobj = size."允许

这使你可以轻松地把现有“枚举值”转换为新方式的枚举值。运气好的话,可以不需要调整它们的使用。

如果你在一个上下文中有超过一个枚举类型,你可以将各个枚举值组织到结构里:

TYPES:
BEGIN OF ENUM tsize STRUCTURE size,
s,
m,
l,
xl,
END OF ENUM tsize STRUCTURE size. DATA dobj TYPE tsize.
dobj = size-xl. "允许

以上代码定义了一个枚举结构size。结构的组件是枚举类型的枚举常量。

枚举对象的常见用处是比较它和枚举常量以决定程序需要切换到哪一个功能分支:

TYPES:
BEGIN OF ENUM tsize STRUCTURE size,
s,
m,
l,
xl,
END OF ENUM tsize STRUCTURE size. DATA dobj TYPE tsize. ... CASE dobj.
WHEN size-s.
...
WHEN size-m.
...
WHEN size-l.
...
WHEN size-xl.
...
ENDCASE.

除此之外,还有一些可以应用的情况:

你可以将枚举对象赋给一个c类型或者string类型的文本。结果就是定义了枚举值的枚举常量的名字。

TYPES:
BEGIN OF ENUM tsize,
size_s,
size_m,
size_l,
size_xl,
END OF ENUM tsize. DATA text TYPE string.
text = size_xl.
cl_demo_output=>display( text ). "结果是SIZE_XL

也可以写作:

DATA(text) = CONV string( size_xl ).

可以使用CONV操作符指定类型来访问当前值:

TYPES:
BEGIN OF ENUM tsize,
size_s,
size_m,
size_l,
size_xl,
END OF ENUM tsize. DATA(value) = CONV i( size_xl ) .
cl_demo_output=>display( value ). "输出结果是3

另一种方式是,可以使用CONV将一个有效的枚举值转换为枚举对象(常规的赋值语句是无法做到的):

TYPES:
BEGIN OF ENUM tsize,
size_s,
size_m,
size_l,
size_xl,
END OF ENUM tsize. DATA(num) = . TRY.
DATA(dobj) = CONV tsize( num ) .
cl_demo_output=>display( dobj ). "Output is SIZE_XL
CATCH cx_sy_conversion_no_enum_value.
...
ENDTRY.

RTTI中也多了一个相应的类CL_ABAP_ENUMDESCR

TYPES:
BEGIN OF ENUM tsize,
size_s,
size_m,
size_l,
size_xl,
END OF ENUM tsize. DATA(size) = VALUE tsize( ). DATA(enum_descr) = CAST cl_abap_enumdescr(
cl_abap_typedescr=>describe_by_data( size ) ). cl_demo_output=>new(
)->write_data( enum_descr->kind "E, for elementary
)->write_data( enum_descr->type_kind "k, new for enumerated type
)->write_data( enum_descr->base_type_kind "I, the base type
)->write_data( enum_descr->members "Table of constants and values
)->display( ).

基本上就是这些内容了。

躺下让ABAP运行时来为你工作吧。要注意枚举类型只能在某些合适的运算位置中出现,并且只能包含预先规定的值。非法的枚举值永远不会在枚举对象中出现。

PS:原文的评论中有人提到,枚举值和数据字典中的domain的固定值很像,为什么二者没有集成关系?

作者的回答是:这个特性实际上已经在设计中了,很有希望出现。具体情况要视资源和优先级而定。

本文链接:http://www.cnblogs.com/hhelibeb/p/7976078.html

英文原文:ABAP News for Release 7.51 – Enumerations

ABAP中的枚举对象的更多相关文章

  1. java 根据值获取枚举对象

    关键方法: /** * 值映射为枚举 * * @param enumClass 枚举类 * @param value 枚举值 * @param method 取值方法 * @param <E&g ...

  2. JS基础_枚举对象中的属性

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. 枚举对象中的属性 for . . in

    枚举对象中的属性:把对象中所有的属性和值都取出来 使用 for . . . in 语句 语法: for(var  变量  in  对象){ } for  . . . in 语句  对象中有几个属性,循 ...

  4. 第三章 EnumUtil根据值获取枚举对象

    项目中使用枚举类的好处这里不再赘述,在使用枚举值时,通常需要根据值来获取枚举对象,下面介绍两种实现方案: 1.在枚举类中定义方法实现 首先给出如下性别枚举类: public enum SexEnum ...

  5. 【译】Java中的枚举

    前言 译文链接:http://www.programcreek.com/2014/01/java-enum-examples/ Java中的枚举跟其它普通类很像,在其内部包含了一堆预先定义好的对象集合 ...

  6. 重温WCF之数据契约中使用枚举(转载)(十一)

    转载地址:http://www.zhuli8.com/wcf/EnumMember.html 枚举类型的定义总是支持序列化的.当我们定义一个新的枚举时,不必应用DataContract特性,就可以在数 ...

  7. 说说Java中的枚举(一)

    在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的.例如星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素组成了四季的“数据集”. ...

  8. 字符串处理:ABAP中的正则表达式

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  9. ruby中迭代器枚举器的理解

    参考<ruby编程语言>5.3迭代器和可枚举对象 迭代器一个迭代器是一个方法,这个方法里面有yield语句,这个方法里的yield语句,与传递给这个方法的块进行数据传输 yield将数据传 ...

随机推荐

  1. 重温CSS3

    基础不牢,地动山摇!没办法,只能重温"经典"! 1.CSS3边框:border-radius; box-shadow; border-image border-radius:r1, ...

  2. 网页的居中显示,使用了margin、clear:both

    很久没写过页面了,现在写起来也觉得捡起来还是挺快的. 当时遇到了这样的问题,我有一个大的div包涵了整个网站,有网页头部,中部还有底部.头部就是一个标题,中部就是几张图片跟文字排版,结果左右两边的图片 ...

  3. 电子笔记本的思考(1)(ver0.3)

    章节:电子笔记本的思考(1)   陶哲轩在<解题·成长·快乐——陶哲轩教你学数学>中着重强调,用纸笔来“缓存”思维对于数学解题的重要性: 用选定的符号表达你所知道的信息,并画一个示意图.把 ...

  4. Mariadb Galera Cluster 群集 安装部署

    #Mariadb Galera Cluster 群集 安装部署 openstack pike 部署  目录汇总 http://www.cnblogs.com/elvi/p/7613861.html # ...

  5. openstack Keystone验证服务集群

    #Keystone验证服务群集 openstack pike 部署 目录汇总 http://www.cnblogs.com/elvi/p/7613861.html ##.Keystone验证服务集群 ...

  6. 实用的jQuery技巧

    1.回到顶部按钮  利用jQuery里的animate和scrollTop方法,你便不需要使用插件创建简单的滚动到顶部动画. // Back to top $('.top').click(functi ...

  7. 实践作业2:黑盒测试实践——在被测系统上录制脚本 Day 5

    1.处理了学生信息管理系统运行的小细节 2.总结了katalon的使用流程如下 a.在Katalon Studio中创建一个自动化测试项目. b.创建一个测试案例,用来写入所有必要的测试步骤 c.编写 ...

  8. caioj 1237: 【最近公共祖先】树上任意两点的距离 在线倍增ST

    caioj 1237: [最近公共祖先]树上任意两点的距离 倍增ST 题目链接:http://caioj.cn/problem.php?id=1237 思路: 针对询问次数多的时候,采取倍增求取LCA ...

  9. 【luogu P1186】玛丽卡

    https://www.luogu.org/problem/show?pid=1186 考虑暴力,枚举图上每一条边删去后跑Dijkstra,取M次的最大值. 仔细想想就会发现删除最短路以外的边对最短路 ...

  10. And【sql语句之为何用and一个字段两个值得不到表中的数据】

    一.[一个表的一个字段的多个条件用and连接] 用and是查不到值的, and是多个条件同时成立, 也就是一个字段是不能同时等于两个值的. '; 二[相同两个表的两个相同字段的查询用and连接] '; ...