欢迎来到萧静默的博客

书山有路勤为径,学海无涯苦作舟。

ABAP对象-面向对象(转)

转自:https://www.jianshu.com/p/f847c8f71438

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.
 

 

 

posted @ 2019-09-02 16:52  萧静默  阅读(2757)  评论(0编辑  收藏  举报