引述
对于纯粹的 ABAP 人员(不从事 Webdynpro 或其他面向对象领域的工作)来说,面向对象 ABAP 的采用正处于缓慢阶段;即使是我,也花了一年的时间才完全完成我的 OO 工作。
就连我自己也遇到过这样的情况,我的一位客户问我,你为什么要用 OO 编程,因为他无法理解。我听得目瞪口呆,这种想法促使我写下这篇文章,以帮助那些在如何转用 OO 方面陷入困境的人。
我已经在 ABAP OO 上看到了很多博客,这将是学习(解释概念和示例)的良好开端,但在迁移到 ABAP OO 时仍然面临一些挑战,例如在哪里以及如何开始,只是放下我对面临的问题和我克服的方法的想法
使用 ABAP OO 的障碍很少
- 了解 OO 的概念,但以前对 OO 一无所知
- 如何在我们的常规工作中落实 RICEF 对象
- 如何利用 OO 的主要优势
这篇博客是写给熟悉 OO 概念但懒于在 ABAP 中实现这些概念的资深开发人员的。在谈论这些内容之前,我想先介绍一下如何熟悉类。
注:本博客只提供方法,不提供任何示例
我将展示一个小的示例报表,从 MARA 获取一些条目,并使用 CL_SALV_TABLE
在这里以四种方式在 ALV 中显示相同的条目:
- 传统编码方式
- OO 方式(仅使用静态方法)-- 掌握类和方法概念的窍门
- OO 方式(仅实例方法)-- 掌握类和方法概念的窍门
- 我使用 OO 的理想方式
- 将报表完全转向 OO 的新方向
传统的编码方式
ABAP
REPORT ysdnblog_classic.
PARAMETERS : p_rows TYPE count DEFAULT '100'.
START-OF-SELECTION.
DATA : it_mara TYPE STANDARD TABLE OF mara.
PERFORM get_data CHANGING it_mara.
PERFORM display USING it_mara.
*&---------------------------------------------------------------------*
*& Form GET_DATA
*&---------------------------------------------------------------------*
FORM get_data CHANGING ch_mara TYPE mara_tt.
SELECT * FROM mara INTO TABLE ch_mara UP TO p_rows ROWS .
ENDFORM. " GET_DATA
*&---------------------------------------------------------------------*
*& Form DISPLAY
*&---------------------------------------------------------------------*
FORM display USING i_mara TYPE mara_tt.
DATA : lr_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = lr_table
CHANGING t_table = i_mara ) .
lr_table->display( ).
ENDFORM. " DISPLAY
OO 方法(只使用静态方法)--掌握类和方法的概念
让我们从类开始,先不解释什么是 STATIC
(静态) 或 INSTANCE
(实例) 方法(请在 Google 上搜索或查阅相关资料)。
初学 OO 的主要开发人员的第一个问题是,我的方法应该是 INSTANCE
方法还是 STATIC
方法?让我们把这个问题留到最后再问吧。
首先,从传统的 ABAP 开始,仅使用 STATIC
方法掌握 OO ABAP 的窍门,上面的报告看起来是这样的:(建议继续编写几个报告/对象)
ABAP
*&---------------------------------------------------------------------*
*& Report Y_CLASS_STATIC
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT y_class_static.
PARAMETERS : p_rows TYPE count DEFAULT '100'.
*----------------------------------------------------------------------*
* CLASS lcl_main DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_main DEFINITION.
PUBLIC SECTION.
CLASS-METHODS : get_data,
display.
PRIVATE SECTION.
CLASS-DATA it_mara TYPE mara_tt.
ENDCLASS. " lcl_main DEFINITION
*----------------------------------------------------------------------*
* CLASS lcl_main IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_main IMPLEMENTATION.
METHOD get_data.
SELECT * FROM mara INTO TABLE lcl_main=>it_mara UP TO p_rows ROWS .
ENDMETHOD. " GET_DATA
METHOD display.
DATA : lr_table TYPE REF TO cl_salv_table.
" Get New Instance for ALV Table Object
cl_salv_table=>factory( IMPORTING r_salv_table = lr_table
CHANGING t_table = lcl_main=>it_mara ) .
lr_table->display( ).
ENDMETHOD. " display
ENDCLASS. " lcl_main IMPLEMENTATION
START-OF-SELECTION.
lcl_main=>get_data( ).
lcl_main=>display( ).
好了。.. 我希望你现在已经了解了传统报表在 CLASS/METHODS 中的样子。
OO 方式(仅限实例方法)------掌握类和方法概念
下一步是什么?让我们看看带有实例方法的相同程序。其他步骤包括声明一个对象并将其实例化,以便在程序中使用。
ABAP
*&---------------------------------------------------------------------*
*& Report Y_CLASS_INSTANCE
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT y_class_instance.
PARAMETERS : p_rows TYPE count DEFAULT '100'.
*----------------------------------------------------------------------*
* CLASS lcl_main DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_main DEFINITION.
PUBLIC SECTION.
METHODS : get_data ,
display.
PRIVATE SECTION.
DATA it_mara TYPE mara_tt.
ENDCLASS. "lcl_main definition
*----------------------------------------------------------------------*
* CLASS lcl_main IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_main IMPLEMENTATION.
METHOD get_data.
SELECT * FROM mara INTO TABLE me->it_mara UP TO p_rows ROWS .
ENDMETHOD. " get_data
METHOD display.
DATA : lr_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory(
IMPORTING
r_salv_table = lr_table
CHANGING
t_table = me->it_mara ) .
lr_table->display( ).
ENDMETHOD." display
ENDCLASS." lcl_main implementation
START-OF-SELECTION.
DATA : lr_main TYPE REF TO lcl_main.
CREATE OBJECT lr_main.
lr_main->get_data( ).
lr_main->display( ).
在上面的示例中,我们声明了一个 LCL_MAIN
类型的对象引用,然后必须使用 CREATE OBJECT
命令来创建一个引用,以便在程序中进一步使用。(同一 LCL_MAIN 可以用不同的名称(多个引用)声明,并根据需求启动)。
请使用上述任何一种方法进行一些实时程序,以真正获得 OO 的初始启动。
我使用 OO 的理想方式
我编写上述程序的理想方式如下。
ABAP
*&---------------------------------------------------------------------*
*& Report Y_CLASS_IDEAL
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT y_class_ideal.
PARAMETERS : p_rows TYPE count DEFAULT '100'.
*----------------------------------------------------------------------*
* CLASS lcl_main DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_main DEFINITION.
PUBLIC SECTION.
CLASS-METHODS : start.
PRIVATE SECTION.
METHODS : get_data ,
display.
CLASS-DATA : lr_main TYPE REF TO lcl_main.
DATA it_mara TYPE mara_tt.
ENDCLASS. " lcl_main DEFINITION
*----------------------------------------------------------------------*
* CLASS lcl_main IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_main IMPLEMENTATION.
METHOD start.
CREATE OBJECT lr_main.
lr_main->get_data( ).
lr_main->display( ).
ENDMETHOD. " start
METHOD get_data.
SELECT * FROM mara INTO TABLE me->it_mara UP TO p_rows ROWS .
ENDMETHOD. " GET_DATA
METHOD display.
DATA : lr_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = lr_table
CHANGING t_table = me->it_mara ) .
lr_table->display( ).
ENDMETHOD. " display
ENDCLASS. " lcl_main IMPLEMENTATION
START-OF-SELECTION.
lcl_main=>start( ).
在这里,我们一个程序只调用一次 START
方法,因此我将其作为一个静态方法和一个静态对象(LR_MAIN
引用同一个类)来处理其余的业务逻辑。(还有很多更好的方法。..)。
报表完全转向 OO 的新趋势
编写报表的新方法包括启动报告的 T-code。让我们从下面的 T-code 创建开始,选择第 3 个选项 "类的方法(OO TRANSACTION)"。
下一步跳转到下面的屏幕,取消 OO TRANSACTION MODEL 复选框,启用另一个字段 LOCAL IN PROGRAM
。
现在为下面的程序提供程序名称、本地类名称和方法。程序如下:
ABAP
*&---------------------------------------------------------------------*
*& Report Y_CLASS_NEW
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT y_class_new.
SELECTION-SCREEN : BEGIN OF SCREEN 200.
PARAMETERS p_rows TYPE count DEFAULT '100'.
SELECTION-SCREEN : END OF SCREEN 200.
*----------------------------------------------------------------------*
* CLASS lcl_main DEFINITION
*----------------------------------------------------------------------*
CLASS lcl_main DEFINITION.
PUBLIC SECTION.
CLASS-METHODS : start.
PRIVATE SECTION.
METHODS : get_data,
display.
CLASS-DATA : lr_main TYPE REF TO lcl_main.
DATA it_mara TYPE mara_tt.
ENDCLASS. " lcl_main DEFINITION
*----------------------------------------------------------------------*
* CLASS lcl_main IMPLEMENTATION
*----------------------------------------------------------------------*
CLASS lcl_main IMPLEMENTATION.
METHOD start.
BREAK-POINT.
CALL SELECTION-SCREEN 200.
IF sy-subrc IS INITIAL.
CREATE OBJECT lr_main.
lr_main->get_data( ).
lr_main->display( ).
ENDIF.
ENDMETHOD. "start
METHOD get_data.
SELECT * FROM mara INTO TABLE me->it_mara UP TO p_rows ROWS .
ENDMETHOD. "GET_DATA
METHOD display.
DATA : lr_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = lr_table
CHANGING t_table = me->it_mara ) .
lr_table->display( ).
ENDMETHOD. "display
ENDCLASS. "lcl_main IMPLEMENTATION
START-OF-SELECTION.
lcl_main=>start( ).
在这里,您可以控制选择屏幕何时触发。上述程序中需要注意的事项:
- 您的选择屏幕被定义为具有不同编号的屏幕,编号为 200
- 您是在
START
方法中明确触发选择屏幕 200,而不是将控制权交给框架。(请注意,AT SELECTION SCREEN
的其他事件将照常工作)。 - 执行事务时,首先会触发事务中指定的方法
通过慢慢适应上述方法,你可以将自己的编码风格转变为 OO。
还有很多其他方法,这只是根据我的经验分享的一点小知识。欢迎提出意见和建议。