ABAP对象-面向对象

1 面向对象基础

不多赘述何为对象与类。简单回顾一下在面向对象特性。

  • 封装 限定内部资源的可见性
  • 多态 相同名称的方法在不同类中不同的体现
  • 继承 派生类
REPORT z_simple_object.
CLASS application DEFINITION.
  PUBLIC SECTION.
    METHODS:show_text.
  PRIVATE SECTION.
    DATA text(100) TYPE c  VALUE 'This is my first ABAP Object'.
ENDCLASS.

CLASS application IMPLEMENTATION.
  METHOD show_text.
  WRITE text.
ENDMETHOD.
ENDCLASS.

DATA ob_app TYPE REF TO application.

START-OF-SELECTION.
  CREATE OBJECT ob_app.
  CALL METHOD ob_app->show_text.
简单ABAP对象

2 类和对象

ABAP中的类由程序内部的局域类和全局类,其作用范围不同。但ABAP中的全局类是通过ABAP工作台中的类创建工具Class Bulider开发的,保存在系统类库程序(Class pool)中,可供所有程序使用;而在程序内部定义的类则一般只应用于本程序,但二者的定义原则和格式是一致的。

1 程序中的类定义

(1)类声明及实现

ABAP使用CLASS/ENDCLASS语句进行类定义,且由声明部分和具体实现部分组成。类声明部分中包含类成员(Component,又称Member,具体包括类的属性,方法和事件等)的名称及说明。

CLASS class DEFINITION.
   PUBLIC SECTION.
      ...
   PROTECTED SECTION.
      ...
   PRIVATE SECTION.
      ...
ENDCLASS.

CLASS class IMPLEMENTATION.
    METHOD ... ENDMETHOD.
     ...
ENDCLASS.
(2)成员可见性

类的各个成员都必须在DEFINITION部分进行声明。在ABAP对象中,共有三种可见性:

  • 公共部分(PUBLIC SECTION)中定义的类成员可以被所有对象使用,包括类方法及派生类中定义的方法。
  • 受保护部分(PROTECTED SECTION) 中定义的类成员只能被类及其派生类中的方法使用,外部不可见。
  • 私有部分(PRIVATE SECTION)中定义的类成员只能被本身的方法所使用。
(3)成员类型

ABAP类中可以定义三种不同类型的成员,分别是属性,方法和事件。根据生存期的不同,由实例成员和静态成员之分。

实例成员仅隶属于一个特定的类实例,即一个对象,而静态成员则属于整个类,是所有的类对象共享的内存区域。
  • 属性
    对于实例属性,使用DATA语句定义,语法与数据对象声明相同;对于静态属性,则使用CLASS-DATA语句进行定义。属性在类的声明部分进行定义。
CLASS vehicle DEFINITION.
    PULIC SECTION.
        CLASS-DATA class_name(10) TYPE c VALUE 'Vehicle'.
    PROTECTED SECTION.
        DATA speed TYPE i.
ENDCLASS.

对于公有组件,可以在属性定义语句中增加READ-ONLY关键字,则该属性不能被类外部读取但可被类的内部方法所修改。这种定义方法避免了每次读取类属性时都需要分配相应的读取方法,因为直接获得类属性要比通过类方法更为高效。

  • 方法
    实例方法只能访问该对象实例中的所有属性和事件,而静态方法则只能访问类的静态属性和事件。
    类方法需要在类的声明和实现两部分进行定义,在类的声明部分说明方法的参数接口,在类的实现部分则通过ABAP代码完成具体的功能。方法的声明关键字为METHODS和CLASS-METHODS;实现部分代码在语句METHOD和ENDMETHOD之间定义。
    方法声明语法如下
METHODS meth
  IMPORTING  ... i TYPE type  ...
  EXPORTING... i TYPE type  ...
  CHANGING ... i TYPE type  ...
  EXCEPTIONS ... i TYPE type  ...
  • Importing 用于定义输入参数
  • Exporting 用于定义输出参数
  • Changing 用于定义输入输出参数
  • Exceptions 用于定义可能出现的异常

在方法实现部分,不需要重复定义这个接口

METHOD meth
    ...
  <ABAP Statement>
    ...
ENDMETHOD.
REPORT z_simple_object.
CLASS vehicle DEFINITION.
  PUBLIC SECTION.
    CLASS-DATA class_name(10) TYPE c VALUE 'Vehicle'.
    METHODS:accelerate,
      show_speed.
  PROTECTED SECTION.
    DATA speed TYPE i.
ENDCLASS.

CLASS vehicle IMPLEMENTATION.
  METHOD accelerate.
    speed = speed + 1.
  ENDMETHOD.
  METHOD show_speed.
    WRITE: / 'Speed:', speed.
  ENDMETHOD.
ENDCLASS.

2 定义系统全局类
可以长期存储,维护供整个系统调用,并在系统间传输。该类型不包含事件块,子程序,屏幕等元素,也不包含共有数据部分,因为也不能分配事务代码。

(1)全局类定于
SE24

对象类型选择

类创建对话框

类属性定义

说明:
level(级别,包括静态属性Static Attr. 实例属性Instance Attr. 常量Constant)
Visibility(可见性,PUBLIC,PROTECTED,PRIVATE)
Attributes(属性),Methods(方法),Parameters(参数接口)
在树形结构中双击方法名称,可以添加该方法的代码


类方法实现
(4)使用全局类
REPORT z_global_class.
DATA: o_vehicle TYPE REF TO z_cl_vehicle,
      count     TYPE i.

START-OF-SELECTION.
  CREATE OBJECT o_vehicle.
  DO 5 TIMES.
    CALL METHOD o_vehicle->accelerate.
  ENDDO.
  CALL METHOD o_vehicle->show_speed.
使用全局类

3 程序中的类实例

ABAP类定义之后,并没有实现任何功能,类似于数据类型定义,实际应用则必须通过类的实例-对象来实现。步骤如下:
1)定义类的声明与实现方法
2)使用DATA语句中的TYPE REF TO 选项参照类类型声明引用变量
3)使用CREATE OBJECT语句创建对象
4)通过"->"或"=>"运算符访问对象或类组件

(1)对象创建与引用

ABAP对象的创建和访问需要通过对象引用进行。在程序中,需要先根据对象类型声明引用类型变量,然后对该变量引用ABAP对象,该引用变量中实际存储的是ABAP对象的内存地址。

(2)访问对象组件

对象创建后,可以通过指向它的引用变量对其进行操作。可以使用的对象组件一般为当前可见的属性和方法,通过引用变量后接运算符“->”访问对象组件。oref->comp其中,oref代表引用类型变量,comp代表要访问的类成员。“->”为对象选择运算符,可以用于访问类中定义的实例组件和静态组件。
对于类中的静态组件而言,还有另外一种访问方式,可以不通过实例和引用变量进行,而是通过类名称本身使用类成员选择运算符“=>”直接对类进行操作。class=>comp

REPORT z_simple_object.
CLASS vehicle DEFINITION.
  PUBLIC SECTION.
    CLASS-DATA class_name(10) TYPE c VALUE 'Vehicle'.
    METHODS:accelerate,
      show_speed.
  PROTECTED SECTION.
    DATA speed TYPE i VALUE 1.
ENDCLASS.

CLASS vehicle IMPLEMENTATION.
  METHOD accelerate.
    speed = speed + 1.
  ENDMETHOD.
  METHOD show_speed.
    WRITE: / 'Speed:', speed.
  ENDMETHOD.
ENDCLASS.

DATA o_vehicle TYPE REF TO vehicle.

START-OF-SELECTION.
  WRITE vehicle=>class_name.
  CREATE OBJECT o_vehicle.
  CALL METHOD o_vehicle->accelerate.
  CALL METHOD o_vehicle->show_speed.

访问类组件

由于引用类型变量本身也可以被定义为类属性,因而可以出现下述的链式访问结构oref1->oref2->comp或者class=>oref->comp
上述的两种运算符提供类的外部访问,在某些情况下,对象本身需要知道自身的地址,可以使用局部引用变量ME,该变量隐式的存在与所有的实例方法中,当方法被调用时,该变量将包含自身的地址指针,这种用法称为对象的自身引用。

访问内容 语法格式
一个对象的实例属性或静态属性 orer->attr
类的静态属性 class=>attr
在类内部访问自身实例属性或静态属性 me->attr 或 attr
对象的实例属性或静态方法 CALL METHOD orer -> meth
类的静态方法 CALL METHOD class=>meth
在类内部访问自身实例方法或静态方法 CALL METHOD me->attr 或 CALL METHOD attr
(3)删除对象

对象占据程序内存,如果后续程序不再使用的对象,应该将其删除。系统对对象的删除操作与引用变量有关,系统将自动定时检测,如果一个对象不再被热任何变量引用,则将其删除,并释放其所占用的内存,这个操作就是通过垃圾回收机制完成。
垃圾收集器定时清除不再使用的对象,包括使用链式引用的对象,也可以被其检测删除。要让其发挥作用,只需简单的使用CLEAR语句初始化所有指向该对象的引用变量或者将引用变量的值改变。

REPORT z_simple_object.
CLASS vehicle DEFINITION.
  PUBLIC SECTION.
    CLASS-DATA class_name(10) TYPE c VALUE 'Vehicle'.
    METHODS:accelerate,
      show_speed.
  PROTECTED SECTION.
    DATA speed TYPE i VALUE 1.
ENDCLASS.

CLASS vehicle IMPLEMENTATION.
  METHOD accelerate.
    speed = speed + 1.
  ENDMETHOD.
  METHOD show_speed.
    WRITE: / 'Speed:', speed.
  ENDMETHOD.
ENDCLASS.

DATA: o_vehicle1 TYPE REF TO vehicle,
      o_vehicle2 LIKE o_vehicle1.

START-OF-SELECTION.
  CREATE OBJECT: o_vehicle1, o_vehicle2.
  o_vehicle1 = o_vehicle2.
  CLEAR o_vehicle2.

该程序中,当o_vehicle1指向新对象后,先创建的对象将被清除,而程序初始化变量o_vehicle2后,由于o_vehicle1仍指向第二个对象,所以该对象依然处于活动状态。

3 方法

1 参数的定义和传递

类方法的参数接口部分是在类声明部分通过METHODS语句定义的,而且该接口不需要在类的实现部分再次出现,参数接口的语法如下:

METHODS meth
  IMPORTING ... [VALUE(Ii) | Ii] TYPE type [OPTIONAL|DEFAULT defi] ...
  EXPORTING ... [VALUE(Ii) | Ii] TYPE type [OPTIONAL|DEFAULT defi] ...
  CHANGING ... [VALUE(Ii) | Ii] TYPE type [OPTIONAL|DEFAULT defi] ...
  RETURNING VALUE(r)
  EXCEPTIONS ... Xi ...
  • IMPORTING 指定一或多个输入参数
  • EXPORTING 指定一或多个输出参数
  • CHANGING 指定一或多个输入输出参数
  • VALUE 指定参数传递形式,VALUE则为值传递,也可使用VALUE中的REFERENCE附加项显示指定引用传递
  • TYPE 指定参数传递形式,也可使用LIKE参照已经定义好的数据对象类型
  • OPTIONAL和DEFAULR 通常情况下,已定义的输入参数必须在调用时进行传递,除非使用OPTIONAL选项指定该参数为可选的,此时程序将使用该参数类型的初始值进行传递,或者是使用DEFAULT选项后指定的默认值。
  • RETURNING 该选项可以替代IMPORTING和EXPORTING

2 调用方法

在调用方法时,除去指定为可选参数之外,所有的参数都必须传递相应的实参值。语法结构如下:

CALL METHOD [oref->|class=>] meth
   EXPORTING ... Ii = Fi ...
   IMPORTING ... Ei = Gi ...
   CHANGING ... Ci = Ci ...
   RECEIVING   r = h
   EXCEPTIONS ... Xi = RCi ...

该语句格式适用于包括类内部直接调用(不需要操作符),实例调用(oref->)和静态调用(class=>)三种情况。其中参数定义时用IMPORTING选项指定的形参i此时将接受CALL METHOD语句中的EXPORTING中传递的实参f;而用EXPORTING指定的形参e此时将通过IMPORTING选项传递给实参g。
方法内部的意外处理与功能模块相似,异常通过RAISE和MESSAGE RAISE语句触发,并通过系统字段SY-SUBRC返回相关错误代码。

REPORT z_method_para.
CLASS vehicle DEFINITION.
  PUBLIC SECTION.
    METHODS: accelerate IMPORTING rate TYPE i,
      show_speed.
  PRIVATE SECTION.
    DATA speed TYPE i VALUE 0.
ENDCLASS.
CLASS vehicle IMPLEMENTATION.
  METHOD accelerate.
    speed = speed + rate.
  ENDMETHOD.
  METHOD show_speed.
    WRITE: / 'Speed:', speed.
  ENDMETHOD.
ENDCLASS.

DATA o_vehicle TYPE REF TO vehicle.

START-OF-SELECTION.
  CREATE OBJECT o_vehicle.
  CALL METHOD o_vehicle->accelerate EXPORTING rate = 2.
  CALL METHOD o_vehicle->accelerate EXPORTING rate = 2.
  CALL METHOD o_vehicle->show_speed.
调用方法

ABAP Objects还提供另一种形式

CALL METHOD [oref->|class=>] meth
   PARAMETER-TABLE ptab.
   EXCEPTION-TABLE etab.

其中实参必须在程序中放置在两个特定类型的内表中,传递给方法。其中参数表ptab可以参照类型组ABAP中的ABAP_PARMBIND(行类型)和ABAP_PARMBIND_TAB(表类型)生成;异常表etab可以参照ABAP_EXCBIND(行类型)和ABAP_EXCBIND_TAB(表类型)生成。

3 函数方法

函数也是一种过程模块其特殊之处是在调用时可以使用操作符(如“=”)来替代过程调用语句,并可作为操作数直接应用于操作语句中。

METHODS meth
   IMPORTING ... [VALUE(Ii)|Ii]  TYPE type [OPTIONAL|DEFAULT def] ...
   RETURNING VALUE(r).

一个函数方法可以拥有任意数量的输入参数,但只有一个输出参数,且输出参数必须为值传递而且需要完全限定其类型。

CALL METHOD [oref->|class=>] meth
  EXPORTING ... Ii = Fi ...
  RECEIVING   r = h.
REPORT z_functional_method.
CLASS circle DEFINITION.
  PUBLIC SECTION.
    METHODS get_area IMPORTING VALUE(i_radius) TYPE i
                     RETURNING VALUE(r_size)   TYPE f.
  PRIVATE SECTION.
    CONSTANTS pi TYPE f VALUE '3.1415926'.
ENDCLASS.
CLASS circle IMPLEMENTATION.
  METHOD get_area.
    r_size = i_radius ** 2 * pi.
  ENDMETHOD.
ENDCLASS.

*
PARAMETERS radius TYPE i.
DATA: o_circle TYPE REF TO circle,
      area     TYPE f.

START-OF-SELECTION.
  CREATE OBJECT o_circle.
  CALL METHOD o_circle->get_area
    EXPORTING
      i_radius = radius
    RECEIVING
      r_size   = area.

  WRITE: / area.
  area = o_circle->get_area( radius ).
  WRITE: / area.
函数方法

4 构造方法

构造方法是由运行时环境自动调用的一种方法,用于为对象设定一个初始状态。构造方法也存在静态和实例两种形式。构造方法并不一定需要在类中定义,系统通常会自行生成一个默认的构造方法,将对象状态设置为初始值。
实例构造方法在每一次对象创建的过程中(即使用CREATE OBJCT语句时)被系统调用,如果在类声明部分进行声明,则需要在实现部分进行代码实现。该方法与一般方法有两点区别:一是有预定义名称CONSTRUCTOR;二是该方法必须在共有部分进行声明。

METHODS constructor
   IMPORTING ... [VALUE(Ii)|Ii] TYPE type [OPTIONAL|DEFAULT def] ...
   EXCEPTIONS ... e ...

构造方法中不包含任何形式的输出参数,其功能只是定义对象状态,而不是对其进行改变。构造方法在CREATE OBJECT语句中被调用,因此根据实例构造方法的定义,该语句本身也可以包含输出参数EXPORTING和返回值EXCEPTION选项。如果在对象创建过程中出现异常,则对象被删除,引用变量设为初始值。

REPORT z_method_constructor.
CLASS vehicle DEFINITION.
  PUBLIC SECTION.
    METHODS: accelerate IMPORTING rate TYPE i,
      constructor IMPORTING i_speed TYPE i,
      show_speed.
  PRIVATE SECTION.
    DATA speed TYPE i VALUE 0.
ENDCLASS.
CLASS vehicle IMPLEMENTATION.
  METHOD accelerate.
    speed = speed + rate.
  ENDMETHOD.
  METHOD show_speed.
    WRITE speed.
  ENDMETHOD.
  METHOD constructor.
    speed = i_speed.
  ENDMETHOD.
ENDCLASS.

DATA o_vehicle TYPE REF TO vehicle.

START-OF-SELECTION.
  CREATE OBJECT o_vehicle EXPORTING i_speed = 4.
  CALL METHOD o_vehicle->accelerate EXPORTING rate = 2.
  CALL METHOD o_vehicle->accelerate EXPORTING rate = 2.
  CALL METHOD o_vehicle->show_speed.
构造方法
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容