
ABAP 继承
一、什么是继承
继承(Inheritance)是使类之间拥有共同的属性及方法的功能。一个类通过分析过程衍生 为更详细且精制的子类,此时子类会继承父类的属性及方法。使用继承的根本原因在于类的 重复利用。
利用继承实现系统时衍生出来的子类中会追加新属性或方法及修改原有的方法。因此 共同的属性和方法反映在父类中,后追加的信息会反映在子类中。用一句话概括继承,如下 所示。
用已经存在的类衍生出新类。
新创建的子类继承超级类中存在的所有组件。
[图 14-11]中类 Vehicle称为超级类(Superclass),从中衍生的类称为子类(Subclass) 创建父类衍生的子类时使用以下语句。
CLASS subclass DEFINITION INHERITING FROM superclass.
在子类中不用附加声明属性和方法。但是子类可以访问超级类的PUBLIC、PROTECTED 组件。子类中虽然存在超级类的 PRIVATE组件,但也需要以相同的名字再次定义。从超级类 继承的子类方法可以访问超级类的PRIVATE属性。
超级类若没有PRIVATE访问权限,则子类会成为父类的复制版。但是,在子类中可以 追加新组件,子类可看做是超级类的分解版本。不过子类只能拥有一个直属超级类。这些情 况在[图 14-12]中说明,且这称为单一继承(SingleInheritance)。
二、重新定义方法
所有子类都拥有超级类的构成要素但无法修改。但是在方法中使用REDEFINITION语 句重新定义方法便可修改其功能。声明方法的部分和超级类的IMPLEMENTATION 部分不 会影响子类中重新定义方法的操作。子类中重新定义的方法会覆盖超级类的原有 IMPLEMENTATION 在子类中的功能。
连接在子类中的所有参照变量可使用重新定义的方法。即使Reference 参照超级类也会调 用重新定义的方法。在重新定义的方法内,可以使用super->语句访问原有的超级类中的方 法。这样可以使子类免去重复编码直接使用超级类的方法。
METHODS meth REDEFINITION.
[例14-12]
REPORT z14_12.
PUBLIC SECTION.
CLASS cIs1 DEFINITION INHERITING FROM obiect.
METHODS: create.
ENDCLASS. "clsI DEFINITION
CLASS cls1 IMPLEMENTATION.
METHOD create.
WRITE: / 'Original method is called'.
ENDMETHOD.
ENDCLASS."clsI IMPLEMENTATION
CLASS cls2 DEFINITION INHERITING FROM cls1.
PIIBII
METHODS: create REDEFINITION.
ENDCLASS. "cls2 DEFINITION
CLASS cls2 IMPLEMENTATION.
METHOD create.
CALL METHOD super->create
WRITE / 'Method is redefined'.
ENDMETHOD.
ENDCLASS. "cls2 IMPLEMENTATION
DATA :go_obj TYPE REF TO cls2.
START-OF-SELECTION.
CREATE OBJECT: go_obj.
CALL METHOD: go obj->create.
[结果 14-12]
Original method is called
Method is redefined
[例 14-12]中类 cls2 是类cls1的子类。类 cls2 中重新定义了超级类的 CREATE 方法。重 新定义的方法内,调用了超级类的CALLMETHODsuper->create.方法被重新定义后,用 WRITE 语句追加了自己的功能。
三、继承与参照变量
[图14-13]显示的是定义指向子类对象的超级类的 参照变量的方法。Class3是Class2的子类,Class2又是 Class1的子类。即右侧的对象都是Classl的实例。类的 参照变量Cref1、2、3分别在参照Class1、2、3且都与 对象连接在一起。但是只有Crefl才能指定Class1的 PUBLIC 组件地址。Crep2可以指定Class1和Class2的 PUBLIC 组件地址。Cref3可以指定所有类的PUBLIC组 件地址。
四、抽象/最终方法和类
ABSTRACT和FINAL语使用方法和类定义抽象、 最终方法和类。抽象方法定义在抽象类中,但在类中无法实现功能,不过可以在类的子 买现。抽家尖九法仍始化创建。Abstract英不能用初始化创建 Final方法无法在子类中重新定义,也不能包含子类。即这两个类只能使用静态组件。
五、类的构成要素的命名空间
[图 14-14]中继承树内的子类包含超级类的所有组件。在前面已经提到,这种超级类的组 件中只显示PUBLIC和PROTECTED属性。所有PUBLIC、PROTECTED组件包含在继承树 中,且属于同一个命名空间里。综上所述,存在于继承树上的组件都拥有唯一的名字。相反, PRIVATE 组件却只在所属类中有唯一的名字。 重新定义方法时,将相同名字的方法重新IMPLEMENTATION 覆盖超级类的方法。但 是重新定义的方法却无法替代原有的方法IMPLEMENTATION。这是因为原超级类的方法名 字已经以唯一的名字保留。前面已经提到,不是调用子类中重新定义的方法,而是调用超级 类的原有方法时要使用super->语句。这种符号称为PseudoReference。
CALL METHOD super->method.
六、继承与静态属性
与类的所有构成要素一样,静态属性在各个继承树上只存在一个。子类可以访问超级类 的PUBLIC和PROTECTED静态属性。相反,超级类可以与子类共享自己的PUBLIC、 PROTECTED属性。在前面已经介绍,静态属性用CLASS-DATA语句定义,而静态方法用 CLASS-METHOD 语定义。下面通过练习再仔细观察关于静态属性和方法。静态属性和方 法是为了制作类的组件而定义的,即使不创建对象也会显示在内存中。即使创建对象使用静 态属性和方法也不会发生错误,但不建议采用此法。 [例14-13]
REPORT z14_13.
*------------------------------------*
* CLASS CLS1 DEFINITION *
*------------------------------------*
CLASS cls1 DEFINITION.
PUBLIC SECTION.
CLASS-DATA gv_var TYPE string.
CLASS-MMETHODS stat meth.
ENDCLASS. "CLS1 DEFINITION
*------------------------------------*
* CLASS CLS1 IMPLEMENTATION *
*------------------------------------*
CLASS cls1 IMPLEMENTATION.
METHOD stat_meth.
WRITE / 'Static method is called.'.
ENDMETHOD.
ENDCLASS. "CLS1 IMPLEMENTATION
*------------------------------------*
* CLASS CLS2 DEFINITION *
*------------------------------------*
CLASS cls2 DEFINITION INHERITING FROM cls1.
ENDCLASS. "CLS2 DEFINITION
START-OF-SELECTION.
cls1=>gv_var = 'Static Attribute'.
WRITE / cls1=>gv_var.
CALL METHOD clsl=>stat meth.
cls2=>gv_var = 'Static Attribute'.
WRITE / cls2->gv_var.
CALL METHOD cls2=>stat meth.
[结果 14-13]
Static Attribute
Static method is called.
Static Attribute
Static method is called.
从[例14-13]中可以看出,用Static定义的属性和方法,即使不创建对象也可利用 静态符号“=>”访问类及修改其属性,另外在子类中也可使用超级类继承的静态属性 和方法。
七、继承和构造函数
在继承中有几项可以控制构造函数的特殊规则。下面了解下这几项规则。
1.实例构造函数
所有类都拥有实例构造函数,调用创建对象的构造函数时使用。前面提到,在继承树上 的组件名字必须唯一,而构造函数却是例外事项。但是要谨记,这些类的实例构造函数在继 承树上保持着完全独立的关系。在子类中不能重新定义超级类的实例构造函数,也不能使用 CALLMETHOD 构造函数语句。若使用此语句会产生没有这个名字的错误信息。创建对象时, 系统会自动调用此函数。若子类包含超级类的Visible 属性,则子类的实例构造函数可以调 用超级类的实例构造函数。每个子类实例创建者需包含CALLMEOTHDSUPER->Constructor 语句。没有明确声明实例构造函数的超级类会默认调用实例构造函数。没有明确定义实例创 建者的超级类会默认调用实例创建者。依此自动调用超级类的实例创建者。调用默认构造函 数时有多个参数可供选择。
METHODS CONTRUCTOR IFINAL].
IIMPORTING(parameter )l
[(RAISINGEXCEPTIONS)(exci)]MOVE f+2(3)TO f2.
下面通过[例 14-14]理解关于实例构造函数的概念。 [例 14-14]
REPORT z14_14.
*------------------------------------*
* CLASS CLSI DEFINITION *
*------------------------------------*
CLASS cls1 DEFINITION.
METHODS CONTRUCTOR.
ENDCLASS. "CLS1 DEFINITION
*------------------------------------*
* CLASS CLS2 DEFINITION *
*------------------------------------*
CLASS cls2 DEFINITION INHERITING FROM cls1.
PUBLIC SECTION.
METHODS CONTRUCTOR.
ENDCLASS. "CLS2 DEFINITION
*------------------------------------*
* CLASS CLS1 IMPLEMENTATION *
*------------------------------------*
CLASS cls1 IMPLEMENTATION.
METHOD CONSTRUCTOR.
WRITE /'CONSTRUCTOR Test'.
ENDMETHOD. "CLS1 IMPLEMENTATION
ENDCLASS.
*------------------------------------*
* CLASS CLS2 IMPLEMENTATION *
*------------------------------------*
CLASS cls2 IMPLEMENTATION.
METHOD CONSTRUCTOR.
super->CONSTRUCTOR( ).
ENDMETHOD. "CLS2 IMPLEMENTATION
ENDCLASS.
START-OF-SELECTION.
DATA: go_crefl TYPE REF TO cls1,
go_cref2 TYPE REF TO cls2.
CREATE OBJECT go_cref2.
[结果 14-14]
CONTRUCTOR Test
在[例 14-14]中,首先在程序执行部分(START-OF-SELECTION)中声明了参照类CLS2 的对象 go_cre2。然后利用此对象创建对象go_cre2。当创建 go_cref2 对象时会自动调用类 CLS2的构造函数方法。此方法还包含调用超级类的构造函数的方法。
2.静态构造函数(STATIC CONSTRUCTOR)
所有类都包含了 class constructor 静态构造函数。此方法在系统中已经存在,且使用类自 身方法之前被调用,另外也没有参数。若在程序中已经指定子类地址(创建对象),则静态构 造函数处于已执行状态。但执行子类静态构造函数之前必须执行所有超级类的静态构造函数 此函数在程序中只能调用一次。
CLASS-METHODS class Constructor.
上面语句只能在类声明的PUBLIC部分使用。所有类包含了已经声明的自身 class constructor 方法。但使用上面语句可以追加所需功能。若没有功能要追加到静态构造函 数中,则不必声明此语句。与其他静态方法一样,静态构造函数也可访问类的静态组件。 [例14-15]
REPORT z14_15.
CLASS cls1 DEFINITION.
PUBLIC SECTION.
CLASS-METHODS class constructor.
ENDCLASS. "CLS1 DEFINITION
CLASS cls1 IMPLEMENTATION.
METHOD class_constructor.
WRITE : 'class constructor is excuted'.
ENDMETHOD.
ENDCLASS. "CLS1 IMPLEMENTATION
START-OF-SELECTION.
DATA: go_cref TYPE REF TO clsl.
CREATE OBJECT go cref.
[结果 14-15]
class constructor is excuted.