1. 程式人生 > >4.4 類的方法(Methods)- 摘自 《SAP ABAP面向對象程序設計:原則、模式及實踐》

4.4 類的方法(Methods)- 摘自 《SAP ABAP面向對象程序設計:原則、模式及實踐》

讀寫 圖片 solid ESS ng- tin 結果 必須 factor

《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面向對象程序設計:原則、模式及實踐》