为什么第二个创建对象会生成一个短转储



我有以下情况。

包含本地接口定义

*&---------------------------------------------------------------------*
*&  Include           ZZZ_INCL_INTERFACE
*&---------------------------------------------------------------------*
INTERFACE lif_test.
  METHODS:
    test.
ENDINTERFACE.                    "lif_test

使用此包含并定义实现此接口的类的报表。

*&---------------------------------------------------------------------*
*& Report  ZZZ_IMPL_A
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT zzz_impl_a.
INCLUDE zzz_incl_interface.
*----------------------------------------------------------------------*
*       CLASS lcl_test_a DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_test_a DEFINITION FINAL.
  PUBLIC SECTION.
    INTERFACES:
      lif_test.
ENDCLASS.                    "lcl_test_a DEFINITION
*----------------------------------------------------------------------*
*       CLASS lcl_test_a IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_test_a IMPLEMENTATION.
  METHOD lif_test~test.
  ENDMETHOD.                    "lif_test~test
ENDCLASS.                    "lcl_test_a IMPLEMENTATION

第二个报告也使用此包含并定义一个新类,该类也实现在包含中定义的相同接口。

*&---------------------------------------------------------------------*
*& Report  ZZZ_IMPL_B
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
REPORT zzz_impl_b.
INCLUDE zzz_incl_interface.
*----------------------------------------------------------------------*
*       CLASS lcl_test_b DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_test_b DEFINITION FINAL.
  PUBLIC SECTION.
    INTERFACES:
      lif_test.
ENDCLASS.                    "lcl_test_b DEFINITION
*----------------------------------------------------------------------*
*       CLASS lcl_test_b IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS lcl_test_b IMPLEMENTATION.
  METHOD lif_test~test.
  ENDMETHOD.                    "lif_test~test
ENDCLASS.                    "lcl_test_b IMPLEMENTATION
CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS:
      main.
ENDCLASS.
CLASS lcl_main IMPLEMENTATION.
  METHOD main.
    DATA:
      l_rif_test TYPE REF TO lif_test.
    CREATE OBJECT l_rif_test TYPE ('PROGRAM=ZZZ_IMPL_BCLASS=LCL_TEST_B').
    CREATE OBJECT l_rif_test TYPE ('PROGRAM=ZZZ_IMPL_ACLASS=LCL_TEST_A').
  ENDMETHOD.
ENDCLASS.
END-OF-SELECTION.
  lcl_main=>main( ).

该行CREATE OBJECT l_rif_test TYPE ('PROGRAM=ZZZ_IMPL_ACLASS=LCL_TEST_A')生成一个简短的转储,指出动态创建的对象不是lif_test的实现。能解释一下为什么会这样吗?它看起来像语言定义中的一个大洞。在一开始就停止任何讨论:不,我不能使用接口的字典定义。

编辑:尝试转换由第二个CREATE OBJECT创建的对象的实例时,会获得更具描述性的短转储。

DATA:
  l_rcl_object TYPE REF TO object.
*...
CREATE OBJECT l_rcl_object TYPE ('PROGRAM=ZZZ_IMPL_ACLASS=LCL_TEST_A').
l_rif_test ?= l_rcl_object.

短转储有它

The content of the source variable does not fit in the target variable.
Source type: "PROGRAM=ZZZ_IMPL_ACLASS=LCL_TEST_A"
Target type: "PROGRAM=ZZZ_IMPL_BINTERFACE=LIF_TEST"

看起来当我在两个地方包含接口的本地定义时,它们变成了两个单独的定义,一个是程序ZZZ_IMPL_B,第二个是ZZZ_IMPL_A

这种行为的原因是 INCLUDE 就是这样做的 - 它在 INCLUDE 语句的位置包含包含的内容,从开发人员的角度来看,这比复制和粘贴略好,但就系统而言是相同的。您可以在不同的程序中获得两个相等但不相同的接口定义。一种解决方案可能是生成报告、子例程池、函数池或包含接口的模块池。这些程序类型生成自己的负载,因此您将获得一个接口 \PROGRAM=ZZZ_MY_SUBROUTINE_POOL\INTERFACE=LIF_TEST,然后您可以从其他程序使用它。请注意,您仍然需要将此子例程池写入存储库,仅将其保留在本地无济于事。

(除此之外,为什么生成全局接口和类不是一个选项?

您应该将类 A 和 B 的定义和实现放在单独的包含中,并将它们与包含主类的报表中的接口一起包含在内。喜欢这个:

report zzz_impl.
include zzz_incl_interface.
include zzz_incl_a.
include zzz_incl_b.
class lcl_main definition final create private.
  public section.
    class-methods:
      main.
endclass.
class lcl_main implementation.
  method main.
    data l_rif_test type ref to lif_test.
    create object l_rif_test type lcl_test_b.
    create object l_rif_test type lcl_test_a.
  endmethod.
endclass.
end-of-selection.
  lcl_main=>main( ).

出现快捷方式转储的原因是因为您尝试使用 \PROGRAM=ZZZ_IMPL_B\INTERFACE=LIF_TEST 类型的变量来引用实现 \PROGRAM=ZZZ_IMPL_A\INTERFACE=LIF_TEST 的对象。


编辑:我不完全确定您的评论是什么意思,但也许您的用例可以生成整个报告?例如:

report zzz_impl_gen.
data source_interface type standard table of char255.
append `interface lif_test.` to source_interface.
append `  methods:` to source_interface.
append `    test.` to source_interface.
append `endinterface.` to source_interface.
data source_class_a type standard table of char255.
append `class lcl_test_a definition final.` to source_class_a.
append `  public section.` to source_class_a.
append `    interfaces:` to source_class_a.
append `      lif_test.` to source_class_a.
append `endclass.` to source_class_a.
append `class lcl_test_a implementation.` to source_class_a.
append `  method lif_test~test.` to source_class_a.
append `  endmethod.` to source_class_a.
append `endclass.` to source_class_a.
data source_class_b type standard table of char255.
append `class lcl_test_b definition final.` to source_class_b.
append `  public section.` to source_class_b.
append `    interfaces:` to source_class_b.
append `      lif_test.` to source_class_b.
append `endclass.` to source_class_b.
append `class lcl_test_b implementation.` to source_class_b.
append `  method lif_test~test.` to source_class_b.
append `  endmethod.` to source_class_b.
append `endclass.` to source_class_b.
data source_main type standard table of char255.
append `class lcl_main definition final create private.` to source_main.
append `  public section.` to source_main.
append `    class-methods:` to source_main.
append `      main.` to source_main.
append `endclass.` to source_main.
append `class lcl_main implementation.` to source_main.
append `  method main.` to source_main.
append `    data l_rif_test type ref to lif_test.` to source_main.
append `    create object l_rif_test type lcl_test_b.` to source_main.
append `    create object l_rif_test type lcl_test_a.` to source_main.
append `    write: / 'Hello, World!'.` to source_main. " Just to test if it works
append `  endmethod.` to source_main.
append `endclass.` to source_main.
data source_form type standard table of char255.
append `form main.` to source_form.
append `  lcl_main=>main( ).` to source_form.
append `endform.` to source_form.
data source_all type standard table of char255.
append `program subpool.` to source_all.
append lines of source_interface to source_all.
append lines of source_class_a to source_all.
append lines of source_class_b to source_all.
append lines of source_main to source_all.
append lines of source_form to source_all.
data generated_program type string.
data message type string.
data sid type string.
generate subroutine pool source_all name generated_program message message shortdump-id sid.
perform ('MAIN') in program (generated_program) if found. " Important, subroutine name must be in upper case!

最新更新