ABAP对象-继承与接口

1 继承

1 多态性的继承实现

在继承中,多态性是通过方法重载及引用变量实现的。即子类可以重新定义 并以不同的方式实现基类中的公有或保护方法,此时类中的方法需为实例方法。在派生类的声明方法,需如下声明MEHTOD meth REDEFINITION.
该方法必须和基类中的方法具有相同的接口,但可以通过不同的代码实现。如果有一个相同的基类,包含多个派生类,则这些派生类都可以重新定义实例方法,从类用户角度讲,不同的类中都存在该操作,但具体实现过程各有不同。当访问基类时,将采用基类中的原始方法实现。访问派生类时,则采用新的派生类方法实现,原有的基类方法被屏蔽,包括通过自身引用运算符“me->”调用方法。
在方法重载过程中,如果在派生类内部仍然需要使用基类中的方法,则可以使用SUPER为关键字来指定其基类CALL METHOD super->meth.

REPORT z_method_redefinition.

CLASS vehicle DEFINITION.
  PUBLIC SECTION.
    METHODS: accelerate, write_status.
  PROTECTED SECTION.
    DATA speed TYPE i.
ENDCLASS.
CLASS plane DEFINITION INHERITING FROM vehicle.
  PUBLIC SECTION.
    METHODS: rise, write_status REDEFINITION.
  PROTECTED SECTION.
    DATA altitude TYPE i.
ENDCLASS.
CLASS ship DEFINITION INHERITING FROM vehicle.
  PUBLIC SECTION.
    METHODS write_status REDEFINITION.
ENDCLASS.

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

CLASS plane IMPLEMENTATION.
  METHOD rise.
    altitude = altitude + 1.
  ENDMETHOD.
  METHOD write_status.
    WRITE: / 'Plane:'.
    CALL METHOD super->write_status.
    WRITE: / 'Altitude:', altitude.
  ENDMETHOD.
ENDCLASS.

CLASS ship IMPLEMENTATION.
  METHOD write_status.
    WRITE: / 'Ship speed:', speed.
  ENDMETHOD.
ENDCLASS.

DATA: plane_ref TYPE REF TO plane,
      ship_ref  TYPE REF TO ship.

START-OF-SELECTION.
  CREATE OBJECT: plane_ref, ship_ref.
  CALL METHOD: plane_ref->accelerate,
  plane_ref->rise,
  plane_ref->write_status,
  ship_ref->accelerate,
  ship_ref->write_status.
继承

2 抽象类和最终类

  • 抽象类和抽象方法

有时一个基类包含多个派生类,但该基类只是作为模板出现的,并不需要有任何对象作为实例,则可以将该类声明为抽象类。

CLASS class DEFINITION ABSTRACT.
  ...
ENDCLASS.

抽象类不能使用CREATE OBJECT语句创建类对象,其主要目的是为了做派生类的模板,实际使用的对象则依照各个派生类创建。
抽象方法定义METHODS meth ABSTRACT ...
一个抽象方法不能在类本身中被实现,而必须在其派生出的非抽象类中实现。因而含有抽象方法的类必须被定义为抽象类。在派生类的实现过程中,即使用REDEFINITION关键字对该抽象方法进行重新定义,其唯一区别在于抽象方法重新定义过程中不能使用SUPER关键字调用该抽象方法。

  • 最终类和最终方法

最终类,是不能被继承的类。

CLASS class DEFINITION FINAL.
  ...
ENDCLASS.

最终方法是不可以重新定义的方法,不一定出现在最终类中,但最终类的所有方法都是最终方法,因而无需指明FINAL关键字。METHODS meth ABSTRACT ...
一个最终类可以同时为抽象类,但此时类中只能包含静态成员。一个最终方法则不可以同时是抽象方法,因为这没有任何意义。

2 接口

1 接口的定义与实现

  • 定义接口

语法格式

INTERFACE intf.
   DATA   ...
   CLASS-DATA  ...
   METHOD   ...
   ...
ENDINTERFACE.

在接口定义内部可以声明的成员与类中的成员相同(包括属性,方法和事件等),但无需著名具体的可见性,因为具体类中实现的所有接口组件成员均为共有成员。同时,接口定义中也只包含成员声明部分,而具体的实现也将在具体类中进行。

  • 实现接口

接口没有自己的实例,因而也不需要进行方法实现,其中方法的实现要通过具体的类进行。在类中实现一个接口的语法格式如下

CLASS class DEFINITION.
   PUBLIC SECTION.
   ...
   INTERFACE: int1,  int2.
   ...
ENDCLASS.

在类定义中,接口的实现只能出现在共有部分,接口中定义的所有组件都将被添加为该类的公有成员。接口intf中的成员icomp在类内部实现过程中以名称intf~icomp的形式出现。在类的实现部分,必须包含所有的接口方法实现。

CLASS class IMPLEMENTATION ...
   ...
     METHOD intf1~imethl1.
      ...
     ENDMETHOD.
      ...
     METHOD intf2~imeth21.
      ...
     ENDMETHOD.
      ...
ENDCLASS.
REPORT z_interface_demo.

INTERFACE status.
  METHODS write.
ENDINTERFACE.

CLASS counter DEFINITION.
  PUBLIC SECTION.
    INTERFACES status.
    METHODS increment.
  PRIVATE SECTION.
    DATA count TYPE i.
ENDCLASS.
CLASS counter IMPLEMENTATION.
  METHOD status~write.
    WRITE: / 'Count in counter is', count.
  ENDMETHOD.
  METHOD increment.
    ADD 1 TO count.
  ENDMETHOD.
ENDCLASS.

CLASS bicycle DEFINITION.
  PUBLIC SECTION.
    INTERFACES status.
    METHODS drive.
  PRIVATE SECTION.
    DATA speed TYPE i.
ENDCLASS.

CLASS bicycle IMPLEMENTATION.
  METHOD status~write.
    WRITE: / 'Speed of bicycle is', speed.
  ENDMETHOD.
  METHOD drive.
    ADD 10 TO speed.
  ENDMETHOD.
ENDCLASS.

DATA: count      TYPE REF TO counter,
      bike       TYPE REF TO bicycle,
      status     TYPE REF TO status,
      status_tab TYPE TABLE OF REF TO status.

START-OF-SELECTION.
  CREATE OBJECT: count, bike.
  DO 5 TIMES.
    CALL METHOD: count->increment,
    bike->drive.
  ENDDO.

  APPEND: count TO status_tab,
  bike TO status_tab.

  LOOP AT status_tab INTO status.
    CALL METHOD status->write.
  ENDLOOP.
接口定义

2 接口引用

接口引用也是一种对象引用,对于包含接口的类对象,除通过类引用访问之外,还可以通过接口引用进行访问。因为接口引用可以指向任何实现该接口的对象。
接口引用变量的定义与对象引用相似,通过TYPES或DATA语句中的TYPE REF TO 选项进行TYPE|DATA iref TYPE REF TO intf.。其中intf是全局或程序中已经定义的接口。接口引用变量iref也可简称为接口引用。通过成员访问运算符“->”(iref->icomp),接口引用可以访问当前指向对象的接口中可见成员,其中的成员方法应该已经在对象所属的类中实现。

  • 通过接口引用访问对象

要访问一个类对象,必须先声明一个基于该类的引用变量,如果该类为一个接口的实现,则可以将该引用变量赋值给一个接口变量,此时接口引用与类引用指向相同的类对象。假设接口变量名为iref,类引用名称为cref,语法格式如下iref = cerf.
如果该接口中包含实例属性attr和实例方法meth,则可以通过类引用变量或者接口引用变量两种方式对其进行访问。
使用类引用访问

cref->intf~attr
CALL METHOD cref->intf~meth.

使用接口引用访问

iref->attr
CALL METHOD iref->meth.

对于接口中定义的静态成员,如果该成员是常量,则只能通过接口引用进行访问intf=>const
对于其他静态接口成员,则可以通过实现该接口的类本身或者类引用进行访问

class = > intf~attr
CALL METHOD class=>intf~meth.
  • 在接口引用间赋值

与类引用类似,可以将接口引用分配给不同的引用变量,还可以在类引用和接口引用之间相互赋值。在赋值过程中,系统须进行语法检查以确定该赋值可以完成。
假设存在类引用cref和接口引用iref,iref1和iref2,下列形式的赋值过程中:iref1 = iref2.系统将进行静态语法检查,此二接口必须参照同一个接口声明,或者iref2所参照的接口是接口iref1的一个成员。
如果使用iref = cref则cref参照的类必须是接口iref的实现。
如果将接口引用赋值给对象引用cref = iref则cref参照的类必须是ABAP预定于的空类OBJECT.
对于其他所有情况,则必须通过强制赋值语句或者强制赋值运算符"?="进行

MOVE iref? TO cref.
cref ?= iref.

在强制赋值时,系统不会出现任何静态语法检查,但系统将在运行时检查目标对象引用变量是否可以指向源变量引用的对象。如果允许则进行赋值,否则将触发可以捕获的运行时错误MOVE_CAST_ERROR。

3 事件

事件是除去属性,方法之外的第三种类成员。这三种组件中,属性用于刻画类对象的状态,方法用于访问或修改对象状态,而事件则用于一个类对象发布其状态的改变,因而其他对象可以捕获该方法并作出响应。

1 定义事件
必须首先在类声明部分声明事件,然后在其中的某个方法中触发事件

  • 定义事件
    事件可以在类或接口的声明部分进行声明。
EVEVTS|CLASS-EVENTS evt
       EXPORTING ... VALUE(Ei) TYPE type [OPTIONAL]  ...

声明事件时,可以使用EXPORTING附加项指定需要向事件处理方法中传递的参数,该参数传递方式恒为值传递。实例事件总是包含一个隐含的参数SENDER,该参数的类型为触发事件的类或接口的对象引用。

  • 触发事件
    一个实例事件可以被类中的任意方法触发,静态事件则可以被静态方法触发。
    RAISE EVENT evt EXPORTING ... e1 = f1 ...
    对于每一个没有被指定OPTIONAL项的形参e,均必须在实例方法中传递一个实参f,自身引用ME对象在被默认的传递至隐含参数SENDER.

2 事件处理方法
事件需要通过方法捕获事件并进行处理,必须首先为该事件定义一个事件处理方法(也可称之为事件处理器,然后在运行时为该事件进行注册)

  • 声明事件处理方法
    任何类都可以为其他类中定义的事件进行处理,同时也可以为自身事件进行处理。
METHODS|CLASS-METHODS
     meth FOR EVENT evt OF cif IMPORTIONG ... e1 ...

一个事件处理方法的接口中只能包含定义在事件evt中的形参,并需遵循事件中的参数属性设定,但事件处理方法不需要使用RAISE EVENT中定义的参数。如果希望使用隐含参数SENDER,则必须将其列入参数接口列表中,该参数允许事件处理方法访问事件触发这,从而返回处理结果。

  • 注册事件处理方法
    要使事件处理方法能够对事件进行响应,必须在运行时为相关事件注册该方法SET HANDLER ... h ... [FOR] ...该语句将处理方法和相关的触发方法进行链接,其语法和使用效果部分取决于事件的类型因此要区分下列四种类型事件
    • 定义在类中的实例事件
    • 定义在接口中的实例事件
    • 定义在类中的静态事件
    • 定义在接口中的静态事件

对于实例事件,在进行处理之前必须在注册语句中使用附加项FOR指定希望注册到的对象。可以指定一个单独的对象作为事件触发者SET HANDLER ... h ... FOR ref.
或者使用FOR ALL INSTANCES附加项为处理器注册所有可以触发该事件的实例SET HANDLET ... h ... FOR ALL INSTANCES.。该注册过程可以作用于目前尚未被创建的实例。
对于静态事件,则不能使用FOR附加项SET HANDLER ... h ...
该注册自动应用于整个类(或所有实现了包含该静态事件的接口类),对于接口中的静态事件,该注册可以应用于目前尚未装载至内存中的类(该类需是此接口的实现)

  • 事件处理事件
    在程序执行到RAISE EVENT语句之后,所有已注册的处理方法(可以有多个处理方法注册至同一事件)都将在下一个语句之前被处理(同步事件触发机制)。如果处理方法本身触发事件,则该处理方法在原方法继续执行之前被重新调用。

3 事件的触发及处理

在实际操作时,要使一个对象的事件处理方法能够捕获另一个对象触发事件,必须先使用SET HANDLER 语句进行注册,这个注册过程中形成了触发对象和响应对象之间的对应关系。当然,也可以同时注册多个处理对象与一个触发对象相对应。

SET HANDLER ... ref_handler->handler ...
                  FOR ref_sender | FOR ALL INSTANCES
                  [ACTIVATION act].

SET HANDLET 语句则创建一个系统内部的事件处理表,为每一个事件注册相应的方法。该表为系统隐含,用户不可见。对于实例事件,事件处理表中包含用于实现处理的方法名称以及注册了的类实例引用,该表通过SET HANDLER语句动态的进行维护。对应静态事件,系统为相关类创建一个实例无关的处理表。一旦事件被触发,系统将查找相关的事件表并执行对应于该事件的实例方法(或对应的静态方法).

REPORT z_class_counter_event.

CLASS vehicle DEFINITION.
  PUBLIC SECTION.
    EVENTS: too_fast exporting value(speed) type  i.
    METHODS: accelerate,
      show_speed.
  PROTECTED SECTION.
    DATA speed TYPE i.
ENDCLASS.

CLASS vehicle IMPLEMENTATION.
  METHOD accelerate.
    speed = speed + 1.
    IF speed > 5.
      RAISE EVENT too_fast exporting speed = 5.
    ENDIF.
  ENDMETHOD.
  METHOD show_speed.
    WRITE: / 'Speed:', speed.
  ENDMETHOD.
ENDCLASS.

CLASS handler DEFINITION.
  PUBLIC SECTION.
    METHODS handle_excess FOR EVENT too_fast OF vehicle importing speed.
ENDCLASS.
CLASS handler IMPLEMENTATION.
  METHOD handle_excess.
    WRITE: / 'Speed can not be too fast.', speed.
  ENDMETHOD.
ENDCLASS.

DATA:o_vehicle TYPE REF TO vehicle,
     o_handle  TYPE REF TO handler.

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

推荐阅读更多精彩内容

  • 设计模式概述 在学习面向对象七大设计原则时需要注意以下几点:a) 高内聚、低耦合和单一职能的“冲突”实际上,这两者...
    彦帧阅读 3,736评论 0 14
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,092评论 1 32
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • 今天中午弟弟弟媳妇三口人来我家玩了,大宝放学回到家,简单的跟他舅舅舅妈打过招呼,就开始看我的手机,本以为...
    暖洋洋的春天阅读 142评论 0 1
  • 真的强烈建议生孩子要趁早,可别没时间没精力去管ta了再生育。异常心疼这种孩子,别说被世界温柔以待了,根本连父母都不...
    GRACE_bibibi阅读 198评论 0 0