ABAP面向对象

ABAP面向对象

1、面向对象基础

一切皆对象,对象的三要素:封装、多态、继承

abap继承只支持单继承

2、类的定义和实现

ABAP定义类方法是分两部分:先定义、后实现, 最后…最后才是调用方法

2.1、类的定义

不同于java等程序,abap类的定义和实现是分开写的,按如下格式

REPORT  zcsdn_lion_obj02.

* 类(CLASS)—定义
CLASS my_ftion DEFINITION.
  PUBLIC SECTION."公共的,可定义方法、属性
    METHODS: show_text.
*METHODS: 方法1,方法2,方法3."多方法的直接用逗号隔开即可

  PROTECTED SECTION."保护的,可定义方法、属性
    DATA weight TYPE p DECIMALS 2.
    
  PRIVATE SECTION."私有的,可定义方法、属性
    DATA text(100) TYPE c VALUE 'ABAP面向对象第一课.'.
ENDCLASS.                    "application DEFINITION

*类(CLASS)—实现
CLASS my_ftion IMPLEMENTATION.
  METHOD show_text.
    WRITE text.
  ENDMETHOD.                    "show_text
ENDCLASS.                    "application DEFINITION


*类内部调用方法:show_text
DATA zs TYPE REF TO my_ftion.

START-OF-SELECTION."此处一定要加此语句,否则会报错:无法执行语句.
  CREATE OBJECT zs.
  CALL METHOD zs->show_text.

在这里插入图片描述

START-OF-SELECTION.的作用,在ALV选择块中做说明

2.2、类的成员

类成员:属性、方法、事件

2.3、类成员的可见性

PUBLIC SECTION——公有: 可被所有对象使用.

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

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

3、类方法

ABAP定义类方法是分两部分:先定义、后实现,最后才是调用

类方法的定义的种类

Methods meth
	IMPORTING...
	EXPORTING...
	RETURNING...
	CHANGING...
	Exceptions...

类方法的调用

Call Method  [oref->|class=>] meth
   Exporting ... i i= f i..."对应定义method中:Importing
   Importing... ei = gi..."对应定义method中:Exporting
   Changing...  ci = ci..."对应定义method中:Changing
   Receiving  r = h"对应定义method中:RETURNING
   Exceptions ...x..."对应定义method中:Exceptions

示例:

1、设置体重=100

2、设置身高=1.74

3、计算以上体重身高的BMI:体重/身高

REPORT  zcsdn_lion_obj01.

* 定义my_person类
CLASS my_person DEFINITION.
* 公共属性
  PUBLIC SECTION.
*开始定义方法.
    METHODS:function01,
                      setwet IMPORTING value(str2) TYPE p ."需要输入参数的,需在定义方法时说明.
    METHODS bmi EXPORTING value(rt) TYPE p.
    METHODS showname RETURNING value(str1) TYPE string."方法需要return值的,需要在定义方法时指定
    METHODS bmi2 EXPORTING value(rt) TYPE p EXCEPTIONS error.

    DATA:name TYPE string VALUE '李四',"姓名.
          age TYPE i,                 "年龄.
          sex TYPE i.                  "性别.
    DATA:height TYPE p DECIMALS 2."身高.

* 类似static静态属性
    CLASS-DATA:qt TYPE i."数量.

*保护属性
  PROTECTED SECTION.

*私有属性
  PRIVATE SECTION.
    DATA:wgt TYPE p DECIMALS 2."体重.

ENDCLASS.                    "person

*----   CLASS person IMPLEMENTATION   -----------*
CLASS my_person IMPLEMENTATION.
*实现方法:function01
  METHOD function01.
    qt = qt + 23.
  ENDMETHOD.                                                "function01

*实现方法:showname,带返回值功能
  METHOD showname.
*str1 = '姓名=' + name.
    CONCATENATE '姓名:' name INTO str1.
  ENDMETHOD.                    "showname

*实现方法:setwet,带赋值功能
  METHOD setwet.
    wgt = str2.
  ENDMETHOD.                    "setwet

*方法需要另行计算的
  METHOD bmi.
    rt =  wgt / height .
  ENDMETHOD.                    "BMI

*方法需要另行计算的
  METHOD bmi2.
    IF height = 0.
      rt = '0.1'.
      RAISE error."此处的error是程序外事先定义好的错误变量,不在此程序中
    ELSE.
      rt = SQRT( wgt / height ).
    ENDIF.
  ENDMETHOD.                                                "BMI2
ENDCLASS.                    "person IMPLEMENTATION




DATA zs TYPE REF TO my_person.

START-OF-SELECTION.
  CREATE OBJECT zs.

* 1、name原来=李四,可以直接通过zs->name=新value,直接变更
  WRITE: '1、属性', /.
  WRITE:'原=',zs->name.
  zs->name = '张三'.
  zs->height = '174'.
  WRITE:/,'新=', zs->name.
  WRITE:/,'height=', zs->height.
  ULINE.

*2、调用普通方法
  WRITE: '2、普通方法', /.
  CALL METHOD zs->function01.
  WRITE:'QT=',zs->qt.
  ULINE.

*3、调用带Importing的方法
  WRITE: '3、Importing的方法', /.
  DATA i_rt3 TYPE p DECIMALS 2 VALUE 100.
  CALL METHOD zs->setwet
    EXPORTING
      str2 = i_rt3.
  WRITE  i_rt3.
  ULINE.

*4、调用带Exporting的方法
  WRITE: '4、Exporting的方法', /.
  DATA i_height4 TYPE p DECIMALS 2.
  DATA i_rt4 TYPE p DECIMALS 2.
  i_height4 = zs->height.
  CALL METHOD zs->bmi
    IMPORTING
      rt = i_rt4.
  WRITE: 'bmi=', i_rt4.
  ULINE.

*5、调用带RETURNING 的方法
  WRITE: '5、RETURNING 的方法', /.
  DATA i_rt5 TYPE string.
  CALL METHOD zs->showname
    RECEIVING
      str1 = i_rt5.
  WRITE i_rt5.
*5.1 returning的另外一种写法
  DATA i_rt51 TYPE string.
  i_rt51 = zs->showname( ).
  WRITE:/,'类实例后用->:zs->showname( ) ', i_rt51.
  i_rt51 = my_person=>qt.
  WRITE:/,'类未实例直接调用的用类本名=>:my_person=>qt',  i_rt51.
  ULINE.

*6、带Exceptions异常方法
  WRITE: '6、Exceptions异常方法', /.
  DATA i_rt6 TYPE p DECIMALS 2.
  zs->height = 0.
  CALL METHOD zs->bmi2
    IMPORTING
      rt    =  i_rt6
    EXCEPTIONS
      error = 1.
  IF sy-subrc <> 0.
    WRITE:'出错拉,除数不能为0'.
  ENDIF.
  WRITE / i_rt6.

在这里插入图片描述

重点说明

1、静态属性qt在定义好时即可使用,其他普通属性方法要在CREATE OBJECT 对象变量.之后才会生效

2、带returning方法的另外一种写法:i_rt51 = zs->showname( ).

3、-> 和 => 的区别:i_rt51 = my_person=>qt.

->:类实例后,调用类的方法、属性

=>:类未实例的,直接用类名=>类的静态方法、静态属性,如有类my_person中有静态属性qt,即可用my_person=>qt

4、类的继承

单继承、多重继承、不同类型继承同一个类,不支持多继承

在这里插入图片描述

类继承的写法

CLASS class DEFINITION [class_options]. 
ENDCLASS.

class_options有三种情况:
1、INHERITING FROM superclass:指向父类
2、ABSTRACT:抽象类,只能被继承,无法实例使用
3、FINAL:最终类,无法被其他类继承

例子

REPORT  zcsdn_lion_obj03.

*--------   定义父类  ------*
CLASS classtop DEFINITION.
  PUBLIC SECTION.
    METHODS:getname EXPORTING value(rt) TYPE string .
ENDCLASS.                    "classtop DEFINITION


*--------   父类的方法  ------*
CLASS classtop IMPLEMENTATION.
  METHOD getname.
    rt = '父类'.
  ENDMETHOD.                    "getname
ENDCLASS.                    "classtop IMPLEMENTATION


*--------   A类  ------*
CLASS classa DEFINITION INHERITING FROM classtop.
  PUBLIC SECTION.
    METHODS:getname REDEFINITION."要注明是方法重写:REDEFINITION
ENDCLASS.                    "classa DEFINITION

*--------   A类的方法  ------*
CLASS classa IMPLEMENTATION.
  METHOD getname.
    rt = '子类A'.
  ENDMETHOD.                    "getname
ENDCLASS.                    "classa IMPLEMENTATION


*--------   B类 ------*
CLASS classb DEFINITION INHERITING FROM classtop.
  PUBLIC SECTION.
    METHODS:getname REDEFINITION."要注明是方法重写:REDEFINITION
ENDCLASS.                    "classb DEFINITION

*--------   B类的方法  ------*
CLASS classb IMPLEMENTATION.
  METHOD getname.
    rt = 'B子类'.
  ENDMETHOD.                    "getname
ENDCLASS.                    "classb IMPLEMENTATION


START-OF-SELECTION.
  DATA ctop TYPE REF TO classtop.
  DATA ca TYPE REF TO classa.
  DATA cb TYPE REF TO classb.

  CREATE OBJECT ctop.
  CREATE OBJECT ca.
  CREATE OBJECT cb.

  DATA i_wa TYPE string.

*调用父类方法
  CALL METHOD ctop->getname
    IMPORTING
      rt = i_wa.
  WRITE / i_wa.
*调用子类A的方法
  CALL METHOD ca->getname
    IMPORTING
      rt = i_wa.
  WRITE / i_wa.
*调用子类B的方法
  CALL METHOD cb->getname
    IMPORTING
      rt = i_wa.
  WRITE / i_wa.
  ULINE.

*另外一种写法
  i_wa = ''.
  data alls TYPE REF TO classtop.
  create OBJECT alls TYPE classa."指向A类
  CALL METHOD alls->getname IMPORTING rt = i_wa.
  WRITE / i_wa.

  create OBJECT alls TYPE classb."指向B类
  CALL METHOD alls->getname IMPORTING rt = i_wa.
  WRITE / i_wa.

重点说明:

1、继承类、父类都按照类定义格式定义,如PUBLIC SECTION./PROTECTED SECTION./ PRIVATE SECTION.

2、继承类的方法不需带参数,只需在方法名后面带:REDEFINITION,如:METHODS:getname REDEFINITION."方法重写

5、类的抽象类和最终类

CLASS class DEFINITION [class_options]. 
ENDCLASS.

class_options有三种情况:
1、INHERITING FROM superclass:指向父类
2、ABSTRACT:抽象类,只能被继承,无法实例使用
3、FINAL:最终类,无法被其他类继承

抽象类例子

REPORT  zcsdn_lion_obj04.

*--------   定义抽象类  ------*
CLASS classtop DEFINITION ABSTRACT.
  PUBLIC SECTION.
    METHODS:getname EXPORTING value(rt) TYPE string .
ENDCLASS.                    "classtop DEFINITION


*--------   父类的方法  ------*
CLASS classtop IMPLEMENTATION.
  METHOD getname.
    rt = '父类'.
  ENDMETHOD.                    "getname
ENDCLASS.                    "classtop IMPLEMENTATION

*--------   A类  ------*
CLASS classa DEFINITION INHERITING FROM classtop.
  PUBLIC SECTION.
    METHODS:getname REDEFINITION."要注明是方法重写:REDEFINITION
ENDCLASS.                    "classa DEFINITION

*--------   A类的方法  ------*
CLASS classa IMPLEMENTATION.
  METHOD getname.
    rt = '子类A'.
  ENDMETHOD.                    "getname
ENDCLASS.                    "classa IMPLEMENTATION


START-OF-SELECTION.

  DATA classmain TYPE REF TO classtop.
*create OBJECT classmain."此处会报错:无法对抽象类生成实例
  CREATE OBJECT classmain TYPE classa.
  DATA i_wa TYPE string.
  CALL METHOD classmain->getname
    IMPORTING
      rt = i_wa.
  WRITE:/,'抽象类输出结果:', i_wa.

在这里插入图片描述

5.1、假如定义的是抽象方法,本类不需实现方法,在子类实现即可
REPORT  zcsdn_lion_obj04.

*--------   定义抽象类  ------*
CLASS classtop DEFINITION ABSTRACT.
  PUBLIC SECTION.
    METHODS:getname ABSTRACT EXPORTING value(rt) TYPE string.
ENDCLASS.                    "classtop DEFINITION


*--------   父类的方法  ------*
CLASS classtop IMPLEMENTATION.
*抽象方法不需实现,在子类中实现即可
ENDCLASS.                    "classtop IMPLEMENTATION

*--------   A类  ------*
CLASS classa DEFINITION INHERITING FROM classtop.
  PUBLIC SECTION.
    METHODS:getname REDEFINITION."要注明是方法重写:REDEFINITION
ENDCLASS.                    "classa DEFINITION

*--------   A类的方法  ------*
CLASS classa IMPLEMENTATION.
  METHOD getname.
    rt = '抽象方法子类A'.
  ENDMETHOD.                    "getname
ENDCLASS.                    "classa IMPLEMENTATION


START-OF-SELECTION.

  DATA classmain TYPE REF TO classtop.
*create OBJECT classmain."此处会报错:无法对抽象类生成实例
  CREATE OBJECT classmain TYPE classa.
  DATA i_wa TYPE string.
  CALL METHOD classmain->getname
    IMPORTING
      rt = i_wa.
  WRITE:/,'抽象方法输出结果:', i_wa.

在这里插入图片描述

备注:抽象方法必须在抽象类中,否则会报错

备注:如定义类(方法)=final,类(方法)中的方法、属性都是final,无法被继承的

6、面向对象接口

接口定义、实现、引用

接口没有类的public/protected/private,默认只有公共成员,并且默认隐藏不写

INTERFACE 接口名.
  DATA ...
  CLASS-DATA ...
  METHOD ...
  ...
ENDINTERFACE.

接口实现放在类中的PUBLIC SECTION中

CLASS class1 DEFINITION.
  PUBLIC SECTION.
    ...
    INTERFACES: 接口变量1, 接口变量2."接口实现在此处
  ...
ENDCLASS.

*在类中实现
CLASS class IMPLEMENTATION.
  ...
  METHOD 接口变量1~成员.
    ...
  ENDMETHOD.
    ...
  METHOD 接口变量2~成员.
    ...
  ENDMETHOD.
  ...
ENDCLASS.

接口引用:

DATA iref TYPE REF TO 接口名.

CREATE OBJECT iref TYPE 类名.

coding例子

REPORT  zcsdn_lion_obj05.

*------ 接口定义  ---------*
INTERFACE intf.
  DATA msg TYPE string.
  METHODS:showmsg.
  CLASS-DATA:qt TYPE i.
ENDINTERFACE.                    "intf


*--------    类定义    ---------*
CLASS topc DEFINITION.
  PUBLIC SECTION.
    INTERFACES:intf.
ENDCLASS.                    "topc DEFINITION


*---------     类实现     ---------*
CLASS topc IMPLEMENTATION.
  METHOD intf~showmsg.
    WRITE:'你好,接口'.
  ENDMETHOD.                    "intf~showmsg
ENDCLASS.                    "topc IMPLEMENTATION


START-OF-SELECTION.
  DATA o_msg TYPE string.
  DATA o_qt TYPE i.
  
*通过类访问接口成员
  DATA myc TYPE REF TO topc.
  CREATE OBJECT myc.
  CALL METHOD myc->intf~showmsg.
  o_msg = myc->intf~msg.
  o_qt = myc->intf~qt.
  ULINE.

*通过接口访问成员
*接口引用
  DATA iref TYPE REF TO intf.
  CREATE OBJECT iref TYPE topc."不是对象,不能直接实例,需要挂靠在实现类中
  CALL METHOD iref->showmsg.
  o_msg = iref->msg.
  o_qt = iref->qt.

6.4 接口引用间赋值

赋值方式:接口对接口、接口对类、类对接口

REPORT  zcsdn_lion_obj05.

*------ 接口定义  ---------*
INTERFACE intf.
  DATA msg TYPE string.
  METHODS:showmsg.
  CLASS-DATA:qt TYPE i.
ENDINTERFACE.                    "intf


*--------    类定义    ---------*
CLASS topc DEFINITION.
  PUBLIC SECTION.
    INTERFACES:intf.
ENDCLASS.                    "topc DEFINITION


*---------     类实现     ---------*
CLASS topc IMPLEMENTATION.
  METHOD intf~showmsg.
    WRITE:'你好,接口'.
  ENDMETHOD.                    "intf~showmsg
ENDCLASS.                    "topc IMPLEMENTATION


START-OF-SELECTION.
  
  DATA myc1 TYPE REF TO topc.
  DATA myc2 TYPE REF TO topc.
  DATA myc3 TYPE REF TO object."类object是所有类的父类,且不需实例(create OBJECT会报错)
  data myinf TYPE REF TO intf.
  
  create OBJECT myc1.
  create OBJECT myinf TYPE topc.
  
*类对类
  myc1 = myc2.
*接口赋值给类
*myc1 = myinf."此处会报错:不能转换,接口对类,只能是基于object
  myc3 = myinf."接口对类,只能是基于object,如果调换位置:object类赋值给接口也会报错
  
*类赋值给接口
  myinf = myc1."正常
*myinf = myc3."此处会报错:不能转换
  myinf ?= myc3."使用强制转换符:?=,就不会报错,但不建议使用

?=:强制转换,不建议使用,使用后检查代码无法确定代码逻辑是否正确,如在运行发现异常而代码没有捕获异常的(如try…catch),程序就会崩溃

7、面向对象事件

事件的关键字:EVENT

示例:模拟一辆汽车在高速公路行驶:加速、减速、警告,条件:高速公路时速:60~120

REPORT  zcsdn_lion_obj06.

*------- 定义车 -----*
CLASS mycar DEFINITION.
  PUBLIC SECTION.
    EVENTS:warning EXPORTING value(sp) TYPE i."警告

    METHODS:sp_fast IMPORTING value(sp_max) TYPE i,"加速
                      sp_slow IMPORTING value(sp_min) TYPE i."减速
*DATA car_sp TYPE i."汽车时速
*DATA car_dw TYPE i."档位
ENDCLASS.                    "mycar IMPLEMENTATION

*-------实现方法----------------*
CLASS mycar IMPLEMENTATION.
  METHOD sp_fast.
*如果速度小于60,加速
    IF sp_max LT 60.
      sp_max = sp_max + 10.
    ELSE.
      RAISE EVENT warning EXPORTING sp = sp_max.
    ENDIF.
  ENDMETHOD.                    "sp_fast

  METHOD sp_slow.
*如果速度大于120,减速
    IF sp_min GT 120.
      sp_min = sp_min - 10.
    ELSE.
      RAISE EVENT warning EXPORTING sp = sp_min .
    ENDIF.
  ENDMETHOD.                    "sp_slow
ENDCLASS.                    "mycar IMPLEMENTATION



*--------  定义一个类实现warning事件 -----------------*
CLASS handle DEFINITION.
  PUBLIC SECTION.
    METHODS:handle_warn FOR EVENT warning OF mycar IMPORTING sp."声明方法是实现事件的
ENDCLASS.                    "handle DEFINITION

*----------------------------------------------------------------------*
*       CLASS handle IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS handle IMPLEMENTATION.
  METHOD handle_warn.
    IF sp GT 120.
      WRITE:'当前速度',sp,',您已超速,请减速'.
    ELSEIF sp LT 60.
      WRITE:'当前速度',sp,',请加速'.
    ELSE.
      WRITE:'当前速度',sp,',保持当前速度'.
    ENDIF.
  ENDMETHOD.                    "handle_warn
ENDCLASS.                    "handle IMPLEMENTATION

START-OF-SELECTION.

  DATA thiscar TYPE REF TO mycar.
  DATA thishandle TYPE REF TO handle.

  CREATE OBJECT thiscar.
  CREATE OBJECT thishandle.

  SET HANDLER thishandle->handle_warn FOR thiscar.
*set HANDLER thishandle->handle_warn FOR ALL INSTANCES."事件响应所有类.



  data runsp type i .
  do 15 times.
    WRITE / sy-index.
    runsp = sy-index * 10.
    CALL METHOD thiscar->sp_fast
    EXPORTING
      sp_max = runsp.
    ENDDO.
    ULINE.

    do 15 times.
    WRITE / sy-index.
    runsp = sy-index * 10.
    CALL METHOD thiscar->sp_slow
    EXPORTING
      sp_min = runsp.
    ENDDO.

在这里插入图片描述

8、全局类

TCode:SE24

在这里插入图片描述
在这里插入图片描述

1、以ZCL_开头命名的,默认创建类

在这里插入图片描述

在这里插入图片描述

2、以ZIF_开头命名的,默认创建接口

在这里插入图片描述

  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值