4.4 类的方法(Methods)- 摘自 《SAP ABAP面向对象程序设计:原则模式及实践》

Posted techtalk

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4.4 类的方法(Methods)- 摘自 《SAP ABAP面向对象程序设计:原则模式及实践》相关的知识,希望对你有一定的参考价值。

《SAP ABAP面向对象程序设计:原则、模式及实践》

 

技术分享图片

https://book.douban.com/subject/30317853/

http://www.duokan.com/shop/tbt/book/179473

https://item.jd.com/12423999.html

https://e.jd.com/30429611.html

 

4.4 类的方法(Methods)

类的方法(Methods),指明类具有的功能。数据和服务包成了一个整体,能够有一系列的行为和动作。

类的方法描述了类对象状态改变和消息传递的行为方式,代表了类对象可以被外部执行的活动。

比如物料类中,可以有获取物料详细信息,打印物料详细信息等方法,外界程序调用。

类的方法的设计,一般采取功能最小化的单一的原则,也就是一个方法只处理一个事情,而非将多种业务放到一个方法中实现。

类的一个方法如何设计呢?除了任务单一,另一个方法是可以用代码行数来进行估量,代码"尽量不超过显示器的一屏",也就是一个独立的方法的代码保持在50行以内。上下滚动屏幕时会大幅增加出错的概率,代码可读性也更高,逻辑也更清楚,对类方法的评估标准可以参考第8章第10节的ABAP代码的重构(Refactoring)。

我们用实例来说明类的方法。

在上一个全局ZCL_CLASS_MATL的基础上,我们会添加2个方法,用于设置和读取MV_NAME属性的值。

如图4-19所示,转到SE24的Methods标签页,添加1个方法,SET_NAME。

 

技术分享图片

技术分享图片

   

   

   

如图4-20所示,方法的级别(Level)设定,有两种定义级别,分别是实例方法(Instance Method),静态方法(Static Method)。具体定义见表4-18,表4-19。

技术分享图片

 技术分享图片

   

   

   

   

技术分享图片

   

方法级别(Level)

Instance Method实例方法

解释

实例方法必须通过类的实例来使用。

实例方法可以操作类的非静态属性,也可以使用类的静态属性。

注意事项

  1. 实例方法需要先创建对象实例才可以调用。

       

    2. 实例方法既可以读写访问类的实例属性,也可以读写访问类的静态属性。

       

    3. 全局类的实例方法相当于局部类中用METHODS 声明的方法。

    CLASS zcl_class_matl DEFINITION.
    PUBLIC SECTION.
    METHODS set_material_type
    IMPORTING
    im_material_type TYPE string.
    ENDCLASS.

技术分享图片

   

   

方法级别(Level)

Static Method静态方法

解释

静态方法与静态属性一样,属于类本身,而不属于具体的某一个类的对象。静态方法只能操作静态属性。

   

静态方法对本身和所有的对象的实例都是共享的,外部有两种访问方式:通过对象来访问(用->操作符)或通过类(用=>操作符)来访问。

DATA :
lo_matl_1 TYPE REF TO zcl_class_matl.

   

CREATE OBJECT lo_matl_1.

   

CALL METHOD zcl_class_matl=>set_material_name
EXPORTING
im_material_name = l_material_name.

CALL METHOD lo_matl_1->set_material_name
EXPORTING
im_material_name = l_material_name.

注意事项

  1. 静态方法内,只能调用类的其他的静态方法,如果调用类的实例方法,会返回"Only static methods can be declared using the short form (method) within a static method ."错误。

       

    2. 静态方法内,只能访问类的静态属性数据,如果试图读取或修改类的实例属性(Instance Attribute)

    ,会返回"Within a static method, you can only access class attributes without further specifications."错误。(不仅写入不允许,读取也不允许)

       

    3. 静态方法内,不可以采用SUPER访问类的父类属性或方法,否则会返回错误"You cannot use "SUPER->" within static methods ."     

       

    4. Public和Protected的静态方法可以被子类继承,但静态方法不可以在子类中被重新定义,否则会产生错误"Static methods cannot be redefined"。

       

    4. Pubic和Protected的静态方法在父类和子类中对对象和类本身都是可见的。

       

    5. 类的构造器是静态方法,对有效。

    CLASS_CONSTRUCTOR Static Method

    对象构造器是实例方法,对对象实例有效。

    CONSTRUCTOR Instance Method

       

    5. 全局类的静态方法相当于局部类中用CLASS-METHODS 声明的方法。

    CLASS zcl_class_matl DEFINITION.
    PUBLIC SECTION.
    CLASS-METHODS set_material_name
    IMPORTING
    value(im_material_name) TYPE string .
    ENDCLASS.

   

之所以不允许静态方法访问实例属性变量,是因为实例属性变量是属于某个对象的,而静态方法在执行时,并不一定存在对象。

   

同样,因为实例方法可以访问实例属性变量,如果允许静态方法调用实例方法,将间接地允许它使用实例属性变量,所以它也不能调用实例方法。

   

   

如图4-21所示,选择方法SET_NAME点击"Parameters"按钮,为该方法添加参数。

 

 

技术分享图片

   

 技术分享图片

如图4-22所示,设定传入Importing参数IV_NAME,类型为CHAR30.

技术分享图片

技术分享图片

   

   

如图4-23所示,方法参数的类型(Type)设定,有4种定义,分别是Importing,Exporting,Changing,Returning。定义见下图。

 

技术分享图片

技术分享图片

   

方法参数的类型(Type)设定,有4种定义,分别是Importing,Exporting,Changing,Returning。定义见表4-20。

技术分享图片

   

参数类型(Type)

解释

Importing

类方法从调用该方法的程序中接收该参数作为输入值

Exporting

类方法将该参数发送给调用该方法的程序中作为输出值。

Changing

类方法首先从调用该方法的程序中接收该参数作为输入值,然后进过加工后,再将该参数发送给调用该方法的程序中作为输出值。

Returning

用于输出的参数,只能传值, Returning只能传递一个参数。

   

   

如图4-24所示,为该方法设定传值方式,"Pass Value",选项表明该参数是否为值还是传引用。

技术分享图片

技术分享图片

   

   

如图4-25所示,点击"Method"按钮,可以返回前一界面,或者直接点击编辑代码按钮(Code),为该方法写入代码。

 

技术分享图片

技术分享图片

   

   

如图4-26所示,开始写入代码,此处代码的意义是将方法的输入参数IV_NAME传入类的属性MV_NAME。

 

技术分享图片

 

技术分享图片

   

   

如图4-27所示,为类添加另外一个方法TEST_PARAMETER,测试参数。

技术分享图片

技术分享图片

   

   

如图4-28所示,为该方法设定参数,用于测试传入参数,传出参数,修改参数,返回参数,按传引用方式传递的参数,其中还有"Pass Value","Optional"等的设定。

技术分享图片

 

技术分享图片

   

   

一般而言,无论值还是传引用,方法内不能对传入的(Importing类型)的参数进行修改(其中,传引用时,试图修改传入参数的值会引发编译错误。传值时,即便修改传入参数,该参数的对应的外部值变量的值也不会变化。)

当方法参数的类型为Exporting,Changing,Returning时,无论引用,还是传值,该参数都可以在方法内被修改,并且会相应改变外部实际变量的值。(其中方法参数的类型为Returning时,方法参数只能采取传值形式)。

   

如表4-21,表4-22,对Pass Reference (引用)和Pass Value(传值)做了定义和解释。

   

   

技术分享图片

   

参数传递方式(Pass Value)

Pass Reference (引用)

解释

不选中"Pass Value",就是Pass Reference。

   

传参数时将变量的存放地址传至参数中, 也就是方法中的参数变量与外部实际变量共享地址内的值,若在方法中参数变量地址中的值改变了, 外部实际变量的值也会跟着改变。

注意事项

方法参数类型为Changing,Exporting,Returning时,在方法内部修改参数值,会相应改变外部实际变量的值。

   

如果参数类型为Importing时,编译时不允许修改传入参数的值,避免逻辑错误,返回错误为"The field "IV_XXX" cannot be changed"。

   

其中,当参数类型为Returning时,Pass Value为自动设定,不可设定为Pass Reference。

   

技术分享图片

   

参数传递方式(Pass Value)

Pass Value(传值

解释

传参数时将数据的值复制一份至另一地址中, 并将传入方法。

   

如果方法参数类型为Importing,在方法内部修改参数值,不会相应改变外部实际变量的值。

   

如果方法参数类型为Exporting,Changing,Returning时,在方法内部修改参数值,会相应改变外部实际变量的值。

注意事项

其中,当参数类型为Returning时,Pass Value为自动设定。

   

如图4-28,"Optional"选项的意义是,如果设定这个标识符,则该参数可以是可选的,不设定该标识符则是必选的,调用方法时该参数是不必须要列在参数列表里的。Exporting参数是默认的可选参数。

如果调用该方法时,必选的参数没有设定,则会返回错误:The obligatory parameter "CV_XXXX" had no value assigned to it.    

   

如图4-29所示,为方法写入代码,代码是分别对几个参数进行赋值,其中输入参数在传引用是不可以被赋值的,否则会报出错误。

 

技术分享图片

技术分享图片

   

   

如图4-30所示,激活该类,使得该类为Active状态。

 

技术分享图片

技术分享图片

   

下面我们说明一下如何调用类的方法。

采用SE80创建测试程序zrep_cls_002,声明类变量go_class_matl1,以及4个参数。

然后调用类的方法test_parameter,根据SAP ABAP一贯的"以己度人"的规则,调用程序在调用方法时,总是从调用者的角度确定输入输出参数。

以下是定义方法和调用方法时类型的匹配:

方法的传入参数IMPORTING对于调用程序来说是传出参数(EXPORTING);

方法的传出参数EXPORTING对于调用程序来说是传入参数(IMPORTING);

方法的可变参数CHANGING对于调用程序来说是可变参数(CHANGING);

方法的返回参数RETURNING对于调用程序来说是获得参数(RECEIVING)。

   

调用格式如下:

CALL METHOD go_class_matl1->test_parameter
EXPORTING
iv_name = gv_i_name "
方法传入参数对应‘EXPORTING
IMPORTING
ev_name = gv_e_name "
方法传出参数对应‘IMPORTING
CHANGING
cv_name = gv_c_name "
方法可变参数对应‘CHANGING
RECEIVING
rv_name = gv_r_name. "
方法返回参数对应‘RECEIVING

   

   

如示例程序4.2,程序如下:

"示例程序4.2

REPORT zrep_cls_002.

"declare class objects
DATA: go_class_matl1 TYPE REF TO zcl_class_matl.

"declare data
DATA: gv_i_name TYPE char30 VALUE ‘importing into class‘.
DATA: gv_e_name TYPE char30 VALUE ‘exporting from class‘.
DATA: gv_c_name TYPE char30 VALUE ‘changing in class‘.
DATA: gv_r_name TYPE char30 VALUE ‘returning from class‘.

"create objects
CREATE OBJECT go_class_matl1.

*call class instance
"assign value to objects
CALL METHOD go_class_matl1->test_parameter
EXPORTING
iv_name = gv_i_name "method importing parameter
IMPORTING
ev_name = gv_e_name "method exporting parameter
CHANGING
cv_name = gv_c_name "method changing parameter
RECEIVING
rv_name = gv_r_name. "method returning parameter

"Print parameters
WRITE :/ ‘gv_i_name‘, gv_i_name.
WRITE :/ ‘gv_e_name‘, gv_e_name.
WRITE :/ ‘gv_c_name‘, gv_c_name.
WRITE :/ ‘gv_r_name‘, gv_r_name.

   

   

如图4-31所示,代码的几个变量,除了传入变量gv_i_name外,其他变量均被方法内的设定值修改。

   

技术分享图片

技术分享图片

   

   

对于OOP的方法,以下两种调用格式皆可。如有一个账户类的存入货币方法,输入参数为存入货币数量,返回参数为账户余额。

第一种为传统的调用格式,需要使用CALL METHOD开头,调用传入传出参数,如示例程序4.3所示。

   

"示例程序4.3

*OOP support this format for calling method -
CALL METHOD lo_account_balance->deposit
EXPORTING
im_deposit_amount = p_deposit
RECEIVING
re_accounnt_balance = l_balance.

   

第二种调用格式,可以直接赋值操作,如果方法只包含单个的传入IMPORTING参数和返回值RETURNING参数,其中的传入参数可以直接写在括号内,返回值则可以作为方法的返回结果直接赋值给变量,如示例程序4.4所示。

   

"示例程序4.4

*New format of calling method.
l_balance = lo_account_balance->deposit( p_deposit ).

 

用第二种方法调用时,如果有多于一个的IMPORTING参数,调用时还需指定参数的名称,如示例程序4.5所示。

"示例程序4.5

*OOP support this format for calling method -
l_balance = lo_account_balance->deposit(
im_param1 = p_deposit
im_param2 = p_deposit
).

   

如果参数中包含了EXPORTING 或CHANGING参数,代码也必须指定他们的参数类型和名称,如示例程序4.6所示。

"示例程序4.6

*OOP support this format for calling method -
l_balance = lo_account_balance->deposit(
EXPORTING
iv_name = l_param
IMPORTING
ev_name = l_param
CHANGING
cv_name = l_param
).

  














































以上是关于4.4 类的方法(Methods)- 摘自 《SAP ABAP面向对象程序设计:原则模式及实践》的主要内容,如果未能解决你的问题,请参考以下文章

php中的魔术方法(Magic methods)和魔术常亮

翻译:《实用的Python编程》04_03_Special_methods

Python Special Methods - 特殊方法

eclipse jbmp 4.4 插件的安装及配置

4.4polymorphic

Groovy编译时元编程 ( AST 语法树分析 | ClassNode 根节点 | 方法 Methods 节点 | 字段 Fields 节点 | 属性 Properties 节点 )