调用方法和方法链接

时间:2019-01-23 14:49:14

标签: sap abap

对于CALL METHOD-静态方法调用(作废),ABAP关键字文档说:“如果将CALL METHOD用于独立方法调用,则不可能进行链式方法调用...”

尽管如此,以下代码还是可以在7.40系统上愉快地执行。这不是独立方法调用的示例吗?否则,我怎么了?

REPORT ZUTEST3.

CLASS class_parent Definition.
   PUBLIC Section.
   METHODS m1 returning value(r) type ref to class_parent.
ENDCLASS.

CLASS class_parent Implementation. 
   Method m1.
       create object r.
       write / 'm1'.
   EndMethod.
ENDCLASS.

start-of-selection.
data cl type ref to class_parent.
CREATE OBJECT cl.
CALL METHOD cl->m1( )->m1( ).

编辑:免责声明

我们正在用Java编写一个用于解析和转换ABAP代码的工具。特别是,我们无意编写新的ABAP代码。但是,相反,我们的工具必须处理所有ABAP,甚至是过时的语句和晦涩的语法变体。此外,我想提一下,我不是ABAP专家。

3 个答案:

答案 0 :(得分:0)

附录2月23日,弗洛里安(Florian)在评论中给出了正确的答案:“我已向docu小组报告了该错误,他们回答说已经报告了该错误,并在最新版本中对其进行了纠正。新声明是: “ 对于没有圆括号的第二个变体,无法进行链式方法调用,并且不能使用运算符NEW和CAST。”

我在下面给出我的原始答案(顺便说一句,我想现在在CALL METHOD static_meth...中,术语“独立方法调用”指的是“ static_meth”部分,因此它指的是两组构造,因此我的答案不准确,SAP的答案是100%正确)


正如我所看到的,文档说术语“独立方法调用”是指这些构造(请注意使用括号),这些构造被声明为过时的:

CALL METHOD method( ).
CALL METHOD method( 25 ).
CALL METHOD method( a = 1 ).
CALL METHOD method( EXPORTING a = 1 ).
CALL METHOD instance->method( ).
CALL METHOD class=>method( ).
etc.

术语“独立方法调用”不涉及这些构造:

CALL METHOD method.
CALL METHOD method EXPORTING a = 1.
CALL METHOD instance->method.
CALL METHOD class=>method.
etc.

我猜想CALL METHOD cl->m1( )属于第一组构造,因此文档中有错误

可能缺少 not ,因为它应应用于第二组构造(例如CALL METHOD method->method( )无效)。

我的结论:您应该阅读“如果不用于独立方法调用,则不可能使用链式方法...”

Florian和SAP的结论:在下面的评论中,Florian向SAP寻求支持,并指出SAP在文档的下一个正式版本中应使用的确切句子


附录(如果您错误地认为文档页面是关于“静态方法”的,请阅读该文档,希望我能弄清楚它不是)。

此问题的答案证明documentation "CALL METHOD - Static Method Call (Obsolete)" 令人困惑

文档标题:此处的“静态方法调用”是指“方法的静态调用” ,而不是“静态方法的调用”(而在其他地方可能具有这种含义)。如果我们可以用书面语言加上括号,那将分别给这两种可能性:

  • 静态(方法调用):方法的静态调用(无论此方法的类型为“ static”还是“ instance”;我们可以对实例方法进行静态调用)
  • (静态方法)调用:调用静态方法

定义:

  • 静态调用:类,接口或方法名称在源代码中被“硬编码”为符号,而不是文本文字,因此编译器可以识别它们(例如,{{1 }})。相反,动态调用意味着名称是通过变量传递的,这些变量仅在运行时才知道(例如CALL METHOD class=>method.)。另外一个documentation page很好地表明“静态方法调用”与“动态方法调用”,它从不谈论“静态方法和实例方法”,仅谈论“静态方法调用”和“动态方法调用”。
  • 静态方法:使用DATA classvar TYPE seoclsname VALUE 'CL_ABAP_TYPEDESCR'. CALL METHOD (classvar)=>(methodvar).声明的方法。例如,静态调用可以为CLASS-METHODS,动态调用可以为cl_ixml=>create( )

文档中的某些东西也使我感到困惑,只是使用了“静态方法”和仅基于静态方法的示例,因为实际上文档页面是关于“静态调用”的,而不是关于静态方法的(实例方法可以已被使用):

  • 语法DATA classvar TYPE seoclsname VALUE 'CL_IXML'. CALL METHOD (classvar)=>create:“ static_meth”在这里是什么意思?实际上,“ static_meth”并不意味着它是静态方法,而是在静态方法调用上下文中的任何方法。如果查看有关“ static calls”和“ dynamic calls”的文档页面,则会看到语法分别为CALL METHOD { static_meth( ) | static_meth( a ) | ...static_meth( ) ...
  • 示例:这三个调用中再次使用了一种静态方法,这三个调用具有完全相同的含义,但是用不同的语法编写,以证明前两个调用已过时,并且仅建议第三个。实际上,所有三个示例都应该更好地使用实例方法来避免混淆!

答案 1 :(得分:0)

首先,方法m1在您的示例中不是静态的,并且从文档中引用它是关于静态方法(CLASS-METHOD)的。

唯一可能的情况就是本例。

REPORT zutest3.

CLASS class_parent DEFINITION.
  PUBLIC SECTION.
    METHODS m1 RETURNING VALUE(r) TYPE REF TO class_parent.
    CLASS-METHODS m1_static RETURNING VALUE(r) TYPE REF TO class_parent.
ENDCLASS.

CLASS class_parent IMPLEMENTATION.
  METHOD m1.
    CREATE OBJECT r.
    WRITE / 'm1'.
  ENDMETHOD.

  METHOD m1_static.
    CREATE OBJECT r.
    WRITE / 'm2'.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
* this seems to be possible but no one sane calls a static method on an object reference
  CALL METHOD class_parent=>m1_static( )->m1_static( ).
* the following two are not possible and will not compile either
*  CALL METHOD class_parent=>m1_static( )=>m1_static( ).
*  class_parent=>m1_static( )=>m1_static( ).

在这种情况下,所有CALL METHOD语句中的第二个仅是冗余,其作用仅是提供信息。

这两个是等效的

CALL METHOD cl->m1( ).
cl->m1( ).

从逻辑上讲,例如

DATA i TYPE i.
COMPUTE i = i + 1.
i = i + 1.

答案 2 :(得分:0)

文档中的错误。我已将其报告给文档小组,他们回答说已经报告了该问题,并在最新版本中对其进行了纠正。

新声明为:

  

对于第二个没有圆括号的变体,链接方法调用   不可能,并且不能使用运算符NEW和CAST。