ABAP-面向对象的开发

送分小仙女□ 提交于 2020-11-14 07:02:00

转载:https://blog.csdn.net/zhongguomao/article/details/70266246

在程序中, 对象的识别和寻址是通过对象引用来实现的,对象引用变量可以访问对象的属性和方法.

ABAP 中的类也有程序内部的局域类和全局类之分, 其作用范围不同.

ABAP中的全局类是通过ABAP工作台中的类创建工具 Class Builder  SE24开发的, 保存在系统类库程序 Class Pool 中, 可供所有程序作用.

一. 程序中类的定义.

1. 类声明及实现

 

* Class Declarations

CLASS application DEFINITION.

 PUBLIC SECTION.

    METHODS: show_text.

 PRIVATE SECTION.

   DATA text(100) TYPE c VALUE 'This is my first ABAP Object.'.

ENDCLASS.

 

 * Class Implementation

CLASS application IMPLEMENTATION.

 METHOD show_text.

   WRITE text.

 ENDMETHOD.

ENDCLASS.

 

2. 成员可见性.

①公有: 可被所有对象使用.

PUBLIC SECTION.

 

②保护: 只能被本类及其派生类中的方法使用.

PROTECTED SECTION.

 

③私有: 只能被类本身的方法所使用.

PRIVATE SECTION.

 

公有部分常常用来定义类的方法, 而类属性则一般定义为类的私有或保护数据, 只能通过自身或其派生类的方法来操作.

 

3. 成员类型.

可定义三种不同类型的成员, 分别是属性, 方法和事件.

属性是在类内部的数据对象, 对于实例属性, 用 DATA 定义, 语法与数据对象声明相同;

对于静态属性(类属性), 使用CLASS-DATA 语句定义, 在类的声明部分定义.

 

* Class Declarations

CLASS application DEFINITION.

 PUBLIC SECTION.

   CLASS-DATA class_name(10) type c value 'Vehicle'.  "静态属性

 PRIVATE SECTION.

   DATA speed TYPE i.

ENDCLASS.

 

对于公有组件还可以在属性定义语句中增加 READ-ONLY 关键字, 则该属性不能被类外部读取但可被类的内部方法所修改.

除 DATA 外, 也可以使用 CONSTANT  语句定义类常量, 必须在类定义时指定其值.

使用 TYPES 语句在类中定义的数据类型, 相当于静态属性, 其定义方法与普通 ABAP 程序类似.

类方法需要在类的声明和实现两部分进行定义, 在类的声明部分说明方法的参数接口, 在实现部分则通过 ABAP代码完成具体的功能.

方法的声明关键字为 METHODS 和 CLASS-METHODS.

 

METHODS meth

 IMPORTING ... i1 TYPE ...

 EXPORTING ... e1 TYPE ...

 CHANGING  ... c1 TYPE ...

 EXCEPTIONS ... x1 TYPE ...

 

定义了方法及方法的参数接口, 和 FORM 相似, 但没有 TABLES 参数.

 

CLASS vehicle DEFINITION.

 PUBLIC SECTION.

   CLASS-DATA class_name(10) TYPE c VALUE 'Vehicle'.

   METHODS: accelerate,

            show_speed.

  PRIVATESECTION.

   DATA speed TYPE i.

ENDCLASS.

 

CLASS vehicle IMPLEMENTATION.

 METHOD accelerate.

   speed = speed + 1.

 ENDMETHOD.

 METHOD show_speed.

   WRITE:  / 'Speed: ', speed.

 ENDMETHOD.

ENDCLASS.

 

二. 定义系统全局类.

通过 Class Builder 工具在类型为 K 的 ABAP 类库程序中定义. 

如果在一个程序中使用该类,则整个类库将被载入到程序内存中.

1. 全局类定义.

可以用 SE80 或 SE24 进入 Class Builder 进行创建.

实例生成:

1、public:决定该类的实例可以被所有的用户创建。

2、protected:只能被其本身或者派生类创建。

3、private:只能通过其自身的方法创建。

选了“最终”则说明全局类不能在程序中被继承。

 

使用全局类.

 


DATA: OB_VE TYPE REF TO Z_CL_VEHICLE.

START-OF-SELECTION.
  CREATE OBJECT OB_VE.
  CALL METHOD OB_VE->ACCELERATE
      .

  CALL METHOD OB_VE->SHOW_SPEED.

 


 

 

三. 程序中的类实例.

 

使用对象的步骤如下:

1) 定义类的声明和实现方法;

2) 使用 DATA 语句中的 TYPE REF TO 参照类类型声明引用变量;

3) 使用CREATE OBJECT 语句创建对象;

4) 通过 ->或 => 运算符访问对象或类组件;

 

1. 对象创建与引用;

ABAP 对象的创建和访问需要通过对象引用进行, 引用类型是ABAP基本类型之一, 

其中包括数据引用和对象引用,

其中对象引用又包括类引用和接口引用. 

对于普通类来说, 应使用类引用.

 

在程序中, 需要先根据对象类型声明引用类型变量, 然后对该变量引用ABAP对象, 该引用变量中实际上存储的是ABAP对象的内在地址, 

因而该引用类型变量也就是普通意义上的指向对象的指针.一个引用类型变量可以不指向任何内存地址或指向一个数据对象, 

但一个ABAP对象则可以同时存在多个指向它的指针, 可以通过所有这些指针对其进行操作.

 

  DATA ob_vehicle TYPE REF TO vehicle.

  CREATEOBJECT ob_vehicle.

 

其中DATA语句创建了一个引用数据对象ob_vehicle , 该数据对象的类型定义为"指向一个类为vehicle的对象的指针".

定义指针之后,CREATE OBJECT 语句则创建了一个类vehicle的实例, 并同时将该对象的地址指针赋给引用类型ob_vehicle.实际情况如下图所示:

 

引用类型与其它类型的数据类型相同, 同类型变量之间也可以相互赋值, 成功赋值之后二者将指向相同的对象.

 

2. 访问对象组件.

对象创建之后, 可以通过指向它的指针(引用变量)对其进行操作. 可以使用的对象组件一般为当前可见的属性和方法, 

通过引用变量后接运算符 -> 访问对象组件. -> 即可以访问类中定义的实例组件又可以访问静态组件. 

但对于静态组件还有另一种访问方式, 通过类名称本身=>直接访问.

oref->comp

其中oref代表引用变量, comp 代表类成员.

class=>comp

其中class代表类名.

由于引用类型变量本身也可以被定义为类属性, 因而可以出现下述的链式访问结构:

oref1->oref2->comp

或者

class=>oref->comp

上述的两种运算符是类的外部访问, 在某些情况下, 对象本身需要知道本身的地址, 可以使用局部引用变量 ME,

该变量隐式的存在于所有的实例方法中, 当方法被调用时, 该变量将包含自身的地址指针, 这种用法称为对象的自身引用.

 

 

3. 删除对象

对象占据程序内存, 如果有后续程序中不再使用的对象, 应该将其删除, 

系统对象的删除操作与引用变量有关, 系统将自动定时进行检测, 如果一个对象不再被任何变量引用, 则将其删除, 并释放其所占的内存, 

这个操作是通过垃圾回收机制来完成的.

垃圾回收机制定时的清除不再使用的对象, 使用 CLEAR 语句初始化所有指向该对象的引用变量或者将引用变量的值改变, 都将触发回收机制.

 

四. 方法.

1. 参数的定义和传递.

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

 

    METHODSmeth

     IMPORTING ... [VALUE(i1)|i1] TYPE type [OPTIONAL|DEFAULT def1] ...

     EXPORTING ... [VALUE(e1)|e1] TYPE type [OPTIONAL] ...

     CHANGE    ... [VALUE(c1)|c1] TYPEtype [OPTIONAL|DEFAULT def1] ...

     RETURNING VALUE(r)

     EXCEPTIONS ... X1 ...

 

2. 调用方法时, 除去指定为可选的参数之外, 所有的参数都必须传递相应的实参值.

 

  CALLMETHOD [oref->|class=>]meth

   EXPORTING...  i1 = f1 ...

       IMPORTING ...  e1 = g1 ...

       CHANGING  ...  c1 = c1 ...

       RECEIVING      r = h

       EXCEPTIONS ... x1 = rc1 ...

 

该语句格式适用于包括类内部直接调用, 实例调用(oref->)和静态调用(class=>)三种情况. 其中参数定义时用IMPORTING选项指定的形参 i 此时将接受 CALL METHOD 语句中用EXPORTING 中传递的实参 f; 而用EXPORTING 选项指定的形参 e 此时将通过 IMPORTING 选项传递给实参 g.

如果方法中只包含输入参数, 而没有输出参数, 则可以使用下列几种形式的简略形式对参数进行调用.

 

CALL METHOD [oref->|class=>]method().

CALL METHOD [oref->|class=>]method(f).

CALL METHOD [oref->|class=>|method(...i1 = f1...).

 

Example:

 

CLASS VEHICLE DEFINITION.
  PUBLIC SECTION.
    CLASS-DATA CLASS_NAME(10TYPE VALUE 'Vehicle'.
    METHODS:SHOW_SPEED,
      ACCELERATE IMPORTING RATE TYPE I.
  PRIVATE SECTION.
    DATA SPEED TYPE I.
ENDCLASS.
CLASS VEHICLE IMPLEMENTATION.
  METHOD ACCELERATE.
    SPEED = SPEED + RATE.
  ENDMETHOD.
  METHOD SHOW_SPEED.
    WRITE:  / 'Speed: ', SPEED.
  ENDMETHOD.
ENDCLASS.

DATA: OB_VEH TYPE REF TO VEHICLE.

START-OF-SELECTION.
  CREATE OBJECT OB_VEH.
  CALL METHOD OB_VEH->ACCELERATE EXPORTING RATE 2.
  CALL METHOD OB_VEH->ACCELERATE EXPORTING RATE 2.
  CALL METHOD OB_VEH->SHOW_SPEED.

 

 

 

方法还可以进行动态调用, 即通过变量对方法名进行指定, 例如下列语句:

  meth = accelerate.

  CALL METHOD ob_veh->(meth).

 

实参的动态传递:

  CALL METHOD [oref->|class=>]meth

   PARAMETER-TABLE ptab

   EXCEPTION-TABLE etab.

 

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

异常表etab 可以参照ABAP_EXCBIND(行类型)和ABAP_EXCBIND_TAB(表类型)生成.

 

3. 函数方法.

函数也是一种过程模块, 其特殊之处是在调用时可以使用操作符(=)来替代过程调用语句, 并可作为操作数直接应用于操作语句中, 因为函数只返回一个唯一的值. 

在ABAP Objects 语法中, 可以用例如函数方法来实现这种函数功能, 形式如下:

 

    METHODSmeth

      IMPORTING... [ VALUE(i1)|i1] TYPE type [OPTIONAL|DEFAULT def1] ...

     RETURNING VALUE(r).

 

一个函数方法可以有多个数量的输入参数, 但只能有一个输出参数, 且该输出参数必须为值传递而且需要完成限定其类型.

函数方法的调用格式如下:

 

CALL METHOD [oref->|class=>]meth

  EXPORTING... i1 = f1 ...

 RECEIVING     r = h.

 

简化的调用形式如下:

 

... [oref->|class=>]method( ) ...

... [oref->|class=>]method(f) ...

... [oref->|class=>]method(... i1 = f1 ...)...

 

 

CLASS CIRCLE DEFINITION.
  PUBLIC SECTION.
    METHODS GET_AREA IMPORTING VALUE(I_RADIUSTYPE 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.
DATA: OB_CIRCLE TYPE REF TO CIRCLE,
      AREA      TYPE F.
PARAMETERS: RADIUS TYPE I.

START-OF-SELECTION.

  CALL METHOD OB_CIRCLE->GET_AREA
    EXPORTING
      I_RADIUS = RADIUS
    RECEIVING
      R_SIZE   = AREA.
  WRITE: / AREA.
  AREA = OB_CIRCLE->GET_AREA( RADIUS ).
  WRITE: / AREA.

 

 

4. 构造和析构方法.

1). 构造方法是运行时环境自动调用的一种方法, 用于为对象设定一个初始化状态, 不能在程序运行过程中由程序代码调用. 

实例构造方法在每一次对象创建的过程中(CREATE OBJECT语句时)被系统调用, 如果在类声明部分进行声明, 则需要在实现部分进行代码实现.

 

METHODS constructor

  IMPORTING... [VALUE(i1)|i1] TYPE type [OPTIONAL|DEFAULT def1] ...

  EXCEPTIONS... e1 ...

 

构造方法中不包含任何形式的输出参数, 其功能只是定义对象状态, 而不是对其进行改变.

类构造方法属于静态方法, 只在程序中被调用一次, 即第一次使用该类时调用, 

该方法也必须在公有部分声明, 其名称必须为 CLASS_CONSTRUCTOR.

 

   CLASS-METHODS class_constructor.

 

类构造方法不包含接口, 而且在其中只能访问类的静态属性.

 

CLASS VEHICLE DEFINITION.
  PUBLIC SECTION.
    CLASS-DATA CLASS_NAME(10TYPE VALUE 'Vehicle'.
    METHODS:SHOW_SPEED,
      ACCELERATE IMPORTING RATE TYPE I,
      CONSTRUCTOR IMPORTING I_SPEED TYPE I"构造函数
  PRIVATE SECTION.
    DATA SPEED TYPE VALUE 0.
ENDCLASS.

CLASS VEHICLE IMPLEMENTATION.
  METHOD CONSTRUCTOR.
    SPEED = I_SPEED.
  ENDMETHOD.
  METHOD ACCELERATE.
    SPEED = SPEED + RATE.
  ENDMETHOD.
  METHOD SHOW_SPEED.
    WRITE:  / 'Speed: ', SPEED.
  ENDMETHOD.
ENDCLASS.

DATA: OB_VEH TYPE REF TO VEHICLE.

START-OF-SELECTION.
  CREATE OBJECT OB_VEH EXPORTING I_SPEED 4"构造函数
  CALL METHOD OB_VEH->SHOW_SPEED.
  CALL METHOD OB_VEH->ACCELERATE
    EXPORTING
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!