ABAP 面向对象(Object Orien…
来源:互联网 发布:微信h5炸金花源码 编辑:程序博客网 时间:2024/06/02 03:57
原文地址:面向对象(Object Orientation) OO">ABAP 面向对象(Object Orientation) OO 作者:SAP169
在程序中, 对象的识别和寻址是通过对象引用来实现的, 对象引用变量可以访问对象的属性和方法.
IMPORTING ... i1 TYPE ... EXPORTING ... e1 TYPE ... CHANGING ... c1 TYPE... EXCEPTIONS ... x1 TYPE ...
DATA ob_vehicle TYPEREF TO vehicle. CREATE OBJECTob_vehicle.
引用类型与其它类型的数据类型相同, 同类型变量之间也可以相互赋值, 成功赋值之后二者将指向相同的对象.
METHODS meth 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 ...
CALL METHOD[oref->|class=>]meth EXPORTING ... i1 = f1 ... IMPORTING ... e1 = g1... CHANGING ... c1 = c1 ... RECEIVING r = h EXCEPTIONS ... x1 = rc1 ...
meth = accelerate. CALL METHODob_veh->(meth).
CALL METHOD[oref->|class=>]meth PARAMETER-TABLEptab EXCEPTION-TABLEetab.
METHODS meth IMPORTING ... [ VALUE(i1)|i1] TYPE type [OPTIONAL|DEFAULT def1]... RETURNING VALUE(r). EXPORTING ... i1 = f1 ... RECEIVING r = h.
CALL METHOD ob_circle->get_area
EXPORTING
i_radius = radius
RECEIVING
r_size = area.
WRITE: / area.
area = ob_circle->get_area( radius ).
WRITE: / area.
IMPORTING ... [VALUE(i1)|i1] TYPE type[OPTIONAL|DEFAULT def1] ... EXCEPTIONS ... e1 ... CLASS-METHODSclass_constructor.
CLASSvehicle 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
rate = 2.
CALL METHOD ob_veh->accelerate
EXPORTING
rate = 2.
CALL METHOD ob_veh->show_speed.
...
参照基类声明的引用变量可以指向其继承类的对象, 如上图所示, 对象 n 是类 Class3的一个实例, 而左侧的三个引用变量CREF1, CREF2, CREF3 则分别参数类 Class1, Class2, Class3 生成. 这三个类存在继承关系.参考基类声明的引用变量也可以指向其派生类, 即三个变量均可以指向对象 n, 但要注意的是 CREF1 只能访问 Class1的公有组件, 而 CREF2 可以访问 Class1 和 Class2的公有组件, CREF3则可以访问全部类的公有组件.
ABAP 中的类也有程序内部的局域类和全局类之分, 其作用范围不同. ABAP中的全局类是通过ABAP工作台中的类创建工具Class Builder 开发的, 保存在系统类库程序 Class Pool 中, 可供所有程序作用.
一. 程序中类的定义.
1. 类声明及实现
* Class Declarations
CLASSapplication DEFINITION.
PUBLIC SECTION.
METHODS: show_text.
PRIVATE SECTION.
DATA text(100) TYPE c VALUE 'This is my first ABAP Object.' .
ENDCLASS.
CLASSapplication IMPLEMENTATION.
METHOD show_text.
WRITE text.
ENDMETHOD.
ENDCLASS.
CLASS
ENDCLASS.
CLASS
ENDCLASS.
2. 成员可见性.
公有: 可被所有对象使用.
PUBLIC SECTION.
保护: 只能被本类及其派生类中的方法使用.
PROTECTED SECTION.
私有: 只能被类本身的方法所使用.
PRIVATE SECTION.
公有部分常常用来定义类的方法, 而类属性则一般定义为类的私有或保护数据, 只能通过自身或其派生类的方法来操作.
3. 成员类型.
可定义三种不同类型的成员, 分别是属性, 方法和事件.
属性是在类内部的数据对象, 对于实例属性, 用 DATA 定义, 语法与数据对象声明相同;
对于静态属性(类属性), 使用 CLASS-DATA 语句定义, 在类的声明部分定义.
* Class Declarations
CLASSapplication DEFINITION.
PUBLIC SECTION.
CLASS-DATA class_name(10) type c value'Vehicle'. "静态属性
PRIVATE SECTION.
DATA speed TYPE i .
ENDCLASS.
CLASS
ENDCLASS.
对于公有组件还可以在属性定义语句中增加 READ-ONLY 关键字,则该属性不能被类外部读取但可被类的内部方法所修改.
除 DATA 外, 也可以使用 CONSTANT 语句定义类常量,必须在类定义时指定其值.
使用 TYPES 语句在类中定义的数据类型, 相当于静态属性, 其定义方法与普通 ABAP 程序类似.
类方法需要在类的声明和实现两部分进行定义, 在类的声明部分说明方法的参数接口, 在实现部分则通过 ABAP代码完成具体的功能.
方法的声明关键字为 METHODS 和 CLASS-METHODS.
METHODS meth
定义了方法及方法的参数接口, 和 FORM 相似, 但没有 TABLES 参数.
CLASS vehicle DEFINITION.
PUBLIC SECTION.
CLASS-DATA class_name(10) TYPE c VALUE 'Vehicle'.
METHODS: accelerate,
show_speed.
PRIVATE SECTION.
DATA speed TYPE i.
ENDCLASS.
CLASSvehicle IMPLEMENTATION.
METHOD accelerate.
speed = speed + 1.
ENDMETHOD.
METHOD show_speed.
WRITE: / 'Speed: ' , speed.
ENDMETHOD.
ENDCLASS.
ENDCLASS.
CLASS
ENDCLASS.
二. 定义系统全局类.
通过 Class Builder 工具在类型为 K 的 ABAP 类库程序中定义. 如果在一个程序中使用该类,则整个类库将被载入到程序内存中.
1. 全局类定义.
可以用 SE80 或 SE24 进入 Class Builder 进行创建.
使用全局类.
REPORT z_af_049.
DATA:ob_veh1 TYPE REF TO z_cl_vehicle1.
START-OF-SELECTION.
CREATE OBJECT ob_veh1.
CALL METHOD ob_veh1->show_speed.
DATA:
START-OF-SELECTION.
三. 程序中的类实例.
使用对象的步骤如下:
1) 定义类的声明和实现方法;
2) 使用 DATA 语句中的 TYPE REF TO 参照类类型声明引用变量;
3) 使用 CREATE OBJECT 语句创建对象;
4) 通过 -> 或 => 运算符访问对象或类组件;
1. 对象创建与引用;
ABAP 对象的创建和访问需要通过对象引用进行, 引用类型是ABAP基本类型之一,其中包括数据引用和对象引用,其中对象引用又包括类引用和接口引用. 对于普通类来说, 应使用类引用.
在程序中, 需要先根据对象类型声明引用类型变量, 然后对该变量引用ABAP对象,该引用变量中实际上存储的是ABAP对象的内在地址,因而该引用类型变量也就是普通意义上的指向对象的指针.一个引用类型变量可以不指向任何内存地址或指向一个数据对象,但一个ABAP对象则可以同时存在多个指向它的指针, 可以通过所有这些指针对其进行操作.
其中DATA语句创建了一个引用数据对象,该数据对象的类型定义为"指向一个类为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语句定义的, 而且该接口不需要在类的实现部分再次出现,参数接口的详细语法形式为:
2. 调用方法时, 除去指定为可选的参数之外, 所有的参数都必须传递相应的实参值.
该语句格式适用于包括类内部直接调用,实例调用(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(10) TYPE c VALUE 'Vehicle'.
METHODS: show_speed,
accelerate importing rate type i.
PRIVATE SECTION.
DATA speed TYPE i.
ENDCLASS.
CLASSvehicle 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.
ENDCLASS.
CLASS
ENDCLASS.
DATA:
START-OF-SELECTION.
方法还可以进行动态调用, 即通过变量对方法名进行指定, 例如下列语句:
实参的动态传递:
其中实参必须在程序中放置在两个特定类型的内表中, 传递给方法,其中参数表ptab可以参照类型组ABAP_PARMBID(行类型)和ABAP_PARMBIND_TAB(表类型)生成; 异常表etab可以参照ABAP_EXCBIND(行类型)和ABAP_EXCBIND_TAB(表类型)生成.
3. 函数方法.
函数也是一种过程模块, 其特殊之处是在调用时可以使用操作符(=)来替代过程调用语句, 并可作为操作数直接应用于操作语句中,因为函数只返回一个唯一的值. 在ABAP Objects 语法中, 可以用例如函数方法来实现这种函数功能, 形式如下:
一个函数方法可以有多个数量的输入参数, 但只能有一个输出参数, 且该输出参数必须为值传递而且需要完成限定其类型.
函数方法的调用格式如下:
CALL METHOD[oref->|class=>]meth
简化的调用形式如下:
... [oref->|class=>]method( )...
... [oref->|class=>]method(f)...
... [oref->|class=>]method(...i1 = f1 ...) ...
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.
CLASScircle IMPLEMENTATION.
METHOD get_area.
r_size = i_radius ** 2 * pi.
ENDMETHOD.
ENDCLASS.
ENDCLASS.
CLASS
ENDCLASS.
DATA: ob_circle TYPE REF TO circle,
area TYPE f.
PARAMETERS: radius TYPE i.
START-OF-SELECTION.
START-OF-SELECTION.
4. 构造和析构方法.
1). 构造方法是运行时环境自动调用的一种方法, 用于为对象设定一个初始化状态, 不能在程序运行过程中由程序代码调用.实例构造方法在每一次对象创建的过程中(CREATE OBJECT语句时)被系统调用, 如果在类声明部分进行声明,则需要在实现部分进行代码实现.
METHODS constructor
构造方法中不包含任何形式的输出参数, 其功能只是定义对象状态,而不是对其进行改变.
类构造方法属于静态方法, 只在程序中被调用一次, 即第一次使用该类时调用, 该方法也必须在公有部分声明, 其名称必须为CLASS_CONSTRUCTOR.
类构造方法不包含接口, 而且在其中只能访问类的静态属性.
REPORT z_af_049.
*Class Declarations
CLASSvehicle DEFINITION.
PUBLIC SECTION.
CLASS-DATA class_name(10) TYPE c VALUE 'Vehicle'.
METHODS: show_speed,
accelerate IMPORTING rate TYPE i,
constructor IMPORTING i_speed TYPE i. "构造函数
PRIVATE SECTION.
DATA speed TYPE i value 0.
ENDCLASS.
*
CLASS
ENDCLASS.
CLASS
ENDCLASS.
DATA:
START-OF-SELECTION.
五. 继承
ABAP 所有的类都是默认继承了系统中的空类 OBJECT.
具有一般性的类称为基类(Superclass), 其各个子类称为派生类(Subclass).
在类定义时, 使用 INHERTING FROM 附加项可以指定派生类和基类之间的继承关系.
CLASS c2 DEFINITION INHERITING FROM c1.
ENDCLASS.
ABAP 中的继承为单一继承, 即一个类可以有多个派生类, 但只能有一个直接基类.
在继承过程中各成员的组件可见性如下:
- 一个派生类中的公有成员包括其本身公有部分定义的成员以及所有基类公有成员, 这些公有成员可以通过选择运算符"->" 在类外部获得.
- 一个派生类中的被保护成员包括其本身被保护部分定义的成员以及所有基类的被保护成员. 这些成员不能通过组件选择运算符"->" 在类外部获得, 但可以在派生类内部使用. 在类外部看, 其行为与类私有成员完全一致.
- 一个派生类中的私有成员只包括其本身私有部分定义的成员. 这些成员只能在派生类内部使用.
因而, 继承类和基类的公有成员和被保护成员享有共同的命名空间, 而私有成员则在不同类之间可以出现重名情况.
参照基类声明的引用变量可以指向其继承类的对象, 如上图所示, 对象 n 是类 Class3的一个实例, 而左侧的三个引用变量CREF1, CREF2, CREF3 则分别参数类 Class1, Class2, Class3 生成. 这三个类存在继承关系.参考基类声明的引用变量也可以指向其派生类, 即三个变量均可以指向对象 n, 但要注意的是 CREF1 只能访问 Class1的公有组件, 而 CREF2 可以访问 Class1 和 Class2的公有组件, CREF3则可以访问全部类的公有组件.
但特别要注意的是: 尽管基类引用变量可以指向其继承类对象, 然而反之则被视为错误的类型转换.
多态性的继承实现.
在继承中, 多态性是通过方法重载及引用变量实现的, 即子类可以重新定义并以不同的方式实现基类中的公有或保护方法,此时基类中的方法需为实例方法.
在派生类中要这样声明:
METHOD meth REDEFINITION.
该方法必须和基类中的方法具有相同的接口, 但可以通过不同的代码实现.
在方法重载过程中, 如果在派生类内部仍然需要使用基类中的方法, 则可以使用 SUPER 关键字来指定其基类.
CALL METHOD super->meth.
Example:
*&---------------------------------------------------------------------*
*&Report Z_AF_050
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT z_af_050.
CLASSclass1 DEFINITION INHERITING FROM object. "基类
PUBLIC SECTION.
METHODS: accelerate,
write_status.
PROTECTED SECTION.
DATA: speed TYPE i.
ENDCLASS.
CLASSplane DEFINITION INHERITING FROM class1.
PUBLIC SECTION.
METHODS: rise,
write_status REDEFINITION. "多态
PROTECTED SECTION.
DATA altitude TYPE i.
ENDCLASS.
CLASSship DEFINITION INHERITING FROM class1.
PUBLIC SECTION.
METHODS: write_status REDEFINITION. "多态
ENDCLASS.
CLASSclass1 IMPLEMENTATION.
METHOD accelerate.
speed = speed + 1.
ENDMETHOD.
METHOD write_status.
WRITE: / 'Speed:', speed.
ENDMETHOD.
ENDCLASS.
CLASSplane IMPLEMENTATION.
METHOD rise.
altitude = altitude + 2.
ENDMETHOD.
METHOD write_status.
WRITE: 'Plane:'.
CALL METHOD super->write_status.
WRITE: / 'Altitude:', altitude.
ENDMETHOD.
ENDCLASS.
CLASSship IMPLEMENTATION.
METHOD write_status.
WRITE: / 'Ship speed:' , speed.
ENDMETHOD.
ENDCLASS.
DATA:plane_ref TYPE REF TO plane.
DATA:ship_ref TYPE REF TO ship.
START-OF-SELECTION.
CREATE OBJECT: plane_ref,
ship_ref.
CALL METHOD: plane_ref->accelerate,
*&
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT
CLASS
ENDCLASS.
CLASS
ENDCLASS.
CLASS
ENDCLASS.
CLASS
ENDCLASS.
CLASS
ENDCLASS.
CLASS
ENDCLASS.
DATA:
DATA:
START-OF-SELECTION.