枚举对象是枚举类型的数据对象。枚举对象只能包含类型为枚举类型的枚举值。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. HTTP协议类

    本文从以下几方面介绍HTTP协议 HTTP协议的主要特点 HTTP报文的组成部分 HTTP方法 HTTP状态码 POST和GET的区别 什么是持久连接 什么是管线化 主要特点: http协议的特点: ...

  2. websocket做手机页面聊天与PC页面聊天一对一的即时通讯

    当时要写这个需求的时候,很头痛,手机端页面的客服功能,相当于QQ这样一个一对一聊天室功能了,瞬间蒙蔽的我也不知道用什么去写这个东西,一开始用ajax,定时器去写,写着写着发现这尼玛不在同一个页面怎么做 ...

  3. Nosql简介 Redis,Memchche,MongoDb的区别

    本篇文章主要介绍Nosql的一些东西,以及Nosql中比较火的三个数据库Redis.Memchache.MongoDb和他们之间的区别.以下是本文章的阅读目录 一.Nosql介绍 1.Nosql简介 ...

  4. Spark SQL中的几种join

    1.小表对大表(broadcast join) 将小表的数据分发到每个节点上,供大表使用.executor存储小表的全部数据,一定程度上牺牲了空间,换取shuffle操作大量的耗时,这在SparkSQ ...

  5. (译)学习JavaScript闭包

    原文地址:https://medium.freecodecamp.org/lets-learn-javascript-closures-66feb44f6a44   闭包是JavaScript中一个基 ...

  6. c语言的typedef

    一.typedef作用简介 1.作用:给已经存在的类型起一个新的名称 2.使用场合: 1> 基本数据类型 2> 指针 3> 结构体 4> 枚举 5> 指向函数的指针 * ...

  7. Less的条件表达式

    Less的条件表达式 当需要根据表达式,而不是参数的值或数量进行匹配时,条件表达式(Guards)就显得非常有用.如果你熟悉函数式编程的话,对条件表达式也不会陌生. 为了尽可能地接近CSS的语言结构, ...

  8. States字段的使用规范

    背景 为了统一数据库表的状态字段,统一数据库表设计,简化字段在程序开发中的使用方式. 解决方式 States对应位域枚举StatesFlags. /// <summary> /// 数据状 ...

  9. JavaScript练习网站收集

    在学习的过程中会发现很多知识点如果不在工作中运用或者手写带验证的话,很容易忘记.任何技能的掌握都是需要不断练习的.在此收集一些自己遇到的JavaScript练习的网站. codewars 国外的一个练 ...

  10. 简单购物车程序(Python)

    #简单购物车程序:money_all=0tag=Trueshop_car=[]shop_info={'apple':10,'tesla':100000,'mac':3000,'lenovo':3000 ...