1

次のようなケースがあります。

ローカルインターフェイス定義のインクルード

*&---------------------------------------------------------------------*
*&  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

また、このインクルードを使用し、インクルードで定義されたものと同じインターフェイスを実装する新しいクラスを定義する2番目のレポート。

*&---------------------------------------------------------------------*
*& 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_B\CLASS=LCL_TEST_B').
    CREATE OBJECT l_rif_test TYPE ('\PROGRAM=ZZZ_IMPL_A\CLASS=LCL_TEST_A').
  ENDMETHOD.
ENDCLASS.

END-OF-SELECTION.
  lcl_main=>main( ).

この行CREATE OBJECT l_rif_test TYPE ('\PROGRAM=ZZZ_IMPL_A\CLASS=LCL_TEST_A')は、動的に作成されたオブジェクトがの実装ではないことを示す短いダンプを生成しますlif_test。なぜそうなのか説明してもらえますか?言語定義の大きな穴のように見えます。最初に議論をやめるには:いいえ、インターフェースの辞書定義を使用することはできません。

編集:2番目に作成されたオブジェクトのインスタンスをキャストしようとすると、より説明的な短いダンプが取得されますCREATE OBJECT

DATA:
  l_rcl_object TYPE REF TO object.
*...
CREATE OBJECT l_rcl_object TYPE ('\PROGRAM=ZZZ_IMPL_A\CLASS=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_A\CLASS=LCL_TEST_A"
Target type: "\PROGRAM=ZZZ_IMPL_B\INTERFACE=LIF_TEST"

インターフェイスのローカル定義を2つの場所に含めると、それらは2つの別個の定義になります。1つはプログラムZZZ_IMPL_Bで、もう1つはZZZ_IMPL_A。です。

4

2 に答える 2

3

この動作の理由は、INCLUDEがまさにそれを行うためです。これには、INCLUDEステートメントの時点でのインクルードの内容が含まれます。これは、開発者の観点からはコピー&ペーストよりもわずかに優れていますが、システムに関しては同じです。心配している。等しいが同一ではない別個のプログラムで2つのインターフェース定義を取得します。1つの解決策は、レポート、サブルーチンプール、関数プール、またはインターフェイスを含むモジュールプールを生成することです。これらのプログラムタイプは独自の負荷を生成するため、他のプログラムから使用できるインターフェイス\ PROGRAM = ZZZ_MY_SUBROUTINE_POOL \ INTERFACE=LIF_TESTを取得します。このサブルーチンプールをリポジトリに書き込む必要があることに注意してください。ローカルに保持するだけでは役に立ちません。

(それ以外に、なぜグローバルインターフェイスとクラスをオプションとして生成しないのですか?)

于 2012-08-13T17:34:14.037 に答える
1

クラス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!
于 2012-08-13T15:20:54.783 に答える