ABAP中的枚举对象
枚举对象是枚举类型的数据对象。枚举对象只能包含类型为枚举类型的枚举值。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 ENUM – END 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中的枚举对象的更多相关文章
- java 根据值获取枚举对象
关键方法: /** * 值映射为枚举 * * @param enumClass 枚举类 * @param value 枚举值 * @param method 取值方法 * @param <E&g ...
- JS基础_枚举对象中的属性
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 枚举对象中的属性 for . . in
枚举对象中的属性:把对象中所有的属性和值都取出来 使用 for . . . in 语句 语法: for(var 变量 in 对象){ } for . . . in 语句 对象中有几个属性,循 ...
- 第三章 EnumUtil根据值获取枚举对象
项目中使用枚举类的好处这里不再赘述,在使用枚举值时,通常需要根据值来获取枚举对象,下面介绍两种实现方案: 1.在枚举类中定义方法实现 首先给出如下性别枚举类: public enum SexEnum ...
- 【译】Java中的枚举
前言 译文链接:http://www.programcreek.com/2014/01/java-enum-examples/ Java中的枚举跟其它普通类很像,在其内部包含了一堆预先定义好的对象集合 ...
- 重温WCF之数据契约中使用枚举(转载)(十一)
转载地址:http://www.zhuli8.com/wcf/EnumMember.html 枚举类型的定义总是支持序列化的.当我们定义一个新的枚举时,不必应用DataContract特性,就可以在数 ...
- 说说Java中的枚举(一)
在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的.例如星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素组成了四季的“数据集”. ...
- 字符串处理:ABAP中的正则表达式
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- ruby中迭代器枚举器的理解
参考<ruby编程语言>5.3迭代器和可枚举对象 迭代器一个迭代器是一个方法,这个方法里面有yield语句,这个方法里的yield语句,与传递给这个方法的块进行数据传输 yield将数据传 ...
随机推荐
- JavaScript学习笔记(八)——变量的作用域与解构赋值
在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...
- 安装memcached
简介 memcached是免费和开放源代码的高性能分布式内存对象缓存系统,旨在通过减轻数据库负载来加速动态Web应用程序.其有以下特点: 基于简单的文本行协议 全部数据按照k/v形式存放在内存中,无持 ...
- Python爬虫利器:Beautiful Soup
Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.使用它来处理HTML页面就像JavaScript代码操作HTML DOM树一样方便.官方中文文档地址 1. 安 ...
- Mina自定义协议简单实现
因公司需要做个电子秤自动称重系统,需要自定义协议实现,所以就用Mina简单实现了一下,有时间改成Netty版 服务端 package net.heartma.server;import java.io ...
- 深入了解Android蓝牙Bluetooth——《进阶篇》
在 [深入了解Android蓝牙Bluetooth--<基础篇>](http://blog.csdn.net/androidstarjack/article/details/6046846 ...
- 实现JavaScript forEach
function forEach(list, callback){ ; n <list.length; n++){ callback.call(list[n], n); } } ,,,,,,,] ...
- 解释器模式(Interpreter)
解释器模式(Interpreter)解释器模式是我们暂时的最后一讲,一般主要应用在OOP开发中的编译器的开发中,所以适用面比较窄. Context类是一个上下文环境类,Plus和Minus分别是用来计 ...
- 《Linux命令行与shell脚本编程大全》第二十二章 gawk进阶
gawk是一门功能丰富的编程语言,你可以通过它所提供的各种特性来编写好几程序处理数据. 22.1 使用变量 gawk编程语言支持两种不同类型的变量: 内建变量和自定义变量 22.1.1 内建变量 ga ...
- PHP入门怎么选?大学生适合学习吗?
大学毕业,面对竞争激烈的社会,理想总是很丰满,现实却很残酷.在硕士.博士都随处可见的今天,本科和大专文凭就显得苍白无力,在面试官问你"有没有工作经验"的时候,你是不是只想起实习期间 ...
- Linux Redis集群搭建与集群客户端实现
硬件环境 本文适用的硬件环境如下 Linux版本:CentOS release 6.7 (Final) Redis版本: Redis已经成功安装,安装路径为/home/idata/yangfan/lo ...