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 0,
       size_m  TYPE tsize VALUE 1,
       size_l  TYPE tsize VALUE 2,
       size_xl TYPE tsize VALUE 3.
     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( 333 ).

枚举是类型和常量的混合体。通过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 = 333. "语法或运行时错误

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

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

TYPES:
  basetype TYPE c LENGTH 2,
  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) = 3.

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

时间: 2024-10-04 17:57:29

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

Floodlight 中创建消息对象的方法

在 floodlight 中创建各种openflow message 和 action 等采用的是简单工厂方式,BasicFactory类(实现OFMessageFactory接口,)会根据消息的类型创建不同的对象,达到更好的封装效果:此外这里调用的是枚举类型的方法.下面是具体代码: ----------工厂接口,还有OFActionFactory,约束需要具体工厂完成的事情 public interface OFMessageFactory { // 根据消息类型得到具体的实例 public 

Java中Enum枚举的使用

注意项: 1.在switch中使用枚举能使代码的可读性更强. 2.如果要自定义方法,那么必须在enum实例序列的最后添加分号.而且Java要求必须先定义enum实例. 3.所有的枚举都继承自java.lang.Enum类,由于Java不支持多继承,所以枚举对象不能再继承其他类. 4.如果想让枚举对应值,那么要写构造方法,也可以再覆盖toString()方法

Iterator的remove方法可保证从源集合中安全地删除对象(转)

import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class IteratorTest{ public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("Test1"); list.add("Test2&qu

浅谈java中的枚举类型(转)

用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. public enum Color { RED, GREEN, BLANK, YELLOW } 用法二:switch JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强. enum Signal { GREEN, YELLOW, RED } pu

Javascript中的Object对象

Object是在javascript中一个被我们经常使用的类型,而且JS中的所有对象都是继承自Object对象的.虽说我们平时只是简单地使用了Object对象来存储数据,并没有使用到太多其他功能,但是Object对象其实包含了很多很有用的属性和方法,尤其是ES5增加的方法,因此,本文将从最基本的介绍开始,详细说明了Object的常用方法和应用. 回到顶部 基础介绍 创建对象 首先我们都知道,对象就是一组相似数据和功能的集合,我们就是用它来模拟我们现实世界中的对象的.那在Javascript中,创

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

项目中使用枚举类的好处这里不再赘述,在使用枚举值时,通常需要根据值来获取枚举对象,下面介绍两种实现方案: 1.在枚举类中定义方法实现 首先给出如下性别枚举类: public enum SexEnum { MAN("M", "男"), WOMAN("F", "女"); private String code; private String desc; SexEnum(String code, String desc) { thi

详解Javascript中的Object对象

Object是在javascript中一个被我们经常使用的类型,而且JS中的所有对象都是继承自Object对象的.虽说我们平时只是简单地使用了Object对象来存储数据,并没有使用到太多其他功能,但是Object对象其实包含了很多很有用的属性和方法,尤其是ES5增加的方法,因此,本文将从最基本的介绍开始,详细说明了Object的常用方法和应用. 基础介绍 创建对象 首先我们都知道,对象就是一组相似数据和功能的集合,我们就是用它来模拟我们现实世界中的对象的.那在Javascript中,创建对象的方

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

声明:原创作品,转载时请注明文章来自SAP师太技术博客:www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将追究法律责任!原文链接:http://www.cnblogs.com/jiangzhengjun/p/4292994.html 正则表达式... 97 ABAP中可以使用regex的地方... 97 正则式语法规则... 98 (?=…).(?!...)100 \A .\z.\Z与^ .$区别... 101 $0….$&.$`.$′102 \1

JAVA中的枚举(一)

在实际编程中,往往存在着这样的"数据集",它们的数值在程序中是稳定的,而且"数据集"中的元素是有限的.例如星期一到星期日七个数据元素组成了一周的"数据集",春夏秋冬四个数据元素组成了四季的"数据集".在Java中想表示这种数据集最容易想到的写法可能是这样,我们以表示一周五天的工作日来举例: public class WeekDay {         public static final int MONDAY = 1;