ABAP面向对象的开发
在程序中, 對(duì)象的識(shí)別和尋址是通過(guò)對(duì)象引用來(lái)實(shí)現(xiàn)的,對(duì)象引用變量可以訪問(wèn)對(duì)象的屬性和方法.
ABAP 中的類也有程序內(nèi)部的局域類和全局類之分, 其作用范圍不同.
ABAP中的全局類是通過(guò)ABAP工作臺(tái)中的類創(chuàng)建工具 Class Builder ?SE24開發(fā)的, 保存在系統(tǒng)類庫(kù)程序 Class Pool 中, 可供所有程序作用.
一. 程序中類的定義.
1. 類聲明及實(shí)現(xiàn)
* Class Declarations
CLASS application DEFINITION.
?PUBLIC SECTION.
??? METHODS: show_text.
?PRIVATE SECTION.
???DATA text(100) TYPE c VALUE 'This is my first ABAP Object.'.
ENDCLASS.
?* Class Implementation
CLASS application IMPLEMENTATION.
?METHOD show_text.
???WRITE text.
?ENDMETHOD.
ENDCLASS.
?
2. 成員可見性.
①公有: 可被所有對(duì)象使用.
PUBLIC SECTION.
?
②保護(hù): 只能被本類及其派生類中的方法使用.
PROTECTED SECTION.
?
③私有: 只能被類本身的方法所使用.
PRIVATE SECTION.
?
公有部分常常用來(lái)定義類的方法, 而類屬性則一般定義為類的私有或保護(hù)數(shù)據(jù), 只能通過(guò)自身或其派生類的方法來(lái)操作.
?
3. 成員類型.
可定義三種不同類型的成員, 分別是屬性, 方法和事件.
屬性是在類內(nèi)部的數(shù)據(jù)對(duì)象, 對(duì)于實(shí)例屬性, 用 DATA 定義, 語(yǔ)法與數(shù)據(jù)對(duì)象聲明相同;
對(duì)于靜態(tài)屬性(類屬性), 使用CLASS-DATA 語(yǔ)句定義, 在類的聲明部分定義.
?
* Class Declarations
CLASS application DEFINITION.
?PUBLIC SECTION.
???CLASS-DATA class_name(10) type c value 'Vehicle'.? "靜態(tài)屬性
?PRIVATE SECTION.
???DATA speed TYPE i.
ENDCLASS.
對(duì)于公有組件還可以在屬性定義語(yǔ)句中增加 READ-ONLY 關(guān)鍵字, 則該屬性不能被類外部讀取但可被類的內(nèi)部方法所修改.
除 DATA 外, 也可以使用 CONSTANT? 語(yǔ)句定義類常量, 必須在類定義時(shí)指定其值.
使用 TYPES 語(yǔ)句在類中定義的數(shù)據(jù)類型, 相當(dāng)于靜態(tài)屬性, 其定義方法與普通 ABAP 程序類似.
類方法需要在類的聲明和實(shí)現(xiàn)兩部分進(jìn)行定義, 在類的聲明部分說(shuō)明方法的參數(shù)接口, 在實(shí)現(xiàn)部分則通過(guò) ABAP代碼完成具體的功能.
方法的聲明關(guān)鍵字為 METHODS 和 CLASS-METHODS.
METHODS meth
?IMPORTING ... i1 TYPE ...
?EXPORTING ... e1 TYPE ...
?CHANGING? ... c1 TYPE ...
?EXCEPTIONS ... x1 TYPE ...
定義了方法及方法的參數(shù)接口, 和 FORM 相似, 但沒有 TABLES 參數(shù).
CLASS vehicle DEFINITION.
?PUBLIC SECTION.
???CLASS-DATA class_name(10) TYPE c VALUE 'Vehicle'.
???METHODS: accelerate,
????????????show_speed.
? PRIVATESECTION.
???DATA speed TYPE i.
ENDCLASS.
CLASS vehicle IMPLEMENTATION.
?METHOD accelerate.
???speed = speed + 1.
?ENDMETHOD.
?METHOD show_speed.
???WRITE:? / 'Speed: ', speed.
?ENDMETHOD.
ENDCLASS.
?
二. 定義系統(tǒng)全局類.
通過(guò) Class Builder 工具在類型為 K 的 ABAP 類庫(kù)程序中定義.?
如果在一個(gè)程序中使用該類,則整個(gè)類庫(kù)將被載入到程序內(nèi)存中.
1. 全局類定義.
可以用 SE80 或 SE24 進(jìn)入 Class Builder 進(jìn)行創(chuàng)建.
實(shí)例生成:
1、public:決定該類的實(shí)例可以被所有的用戶創(chuàng)建。
2、protected:只能被其本身或者派生類創(chuàng)建。
3、private:只能通過(guò)其自身的方法創(chuàng)建。
選了“最終”則說(shuō)明全局類不能在程序中被繼承。
使用全局類.
DATA :?OB_VE? TYPE? REF? TO?Z_CL_VEHICLE .
START-OF-SELECTION .
?? CREATE?OBJECT?OB_VE .
?? CALL? METHOD?OB_VE ->ACCELERATE
?????? .
??CALL?METHOD?OB_VE->SHOW_SPEED.
?
三. 程序中的類實(shí)例.
使用對(duì)象的步驟如下:
1) 定義類的聲明和實(shí)現(xiàn)方法;
2) 使用 DATA 語(yǔ)句中的 TYPE REF TO 參照類類型聲明引用變量;
3) 使用CREATE OBJECT 語(yǔ)句創(chuàng)建對(duì)象;
4) 通過(guò) ->或 => 運(yùn)算符訪問(wèn)對(duì)象或類組件;
?
1. 對(duì)象創(chuàng)建與引用;
ABAP 對(duì)象的創(chuàng)建和訪問(wèn)需要通過(guò)對(duì)象引用進(jìn)行, 引用類型是ABAP基本類型之一,?
其中包括數(shù)據(jù)引用和對(duì)象引用,
其中對(duì)象引用又包括類引用和接口引用.?
對(duì)于普通類來(lái)說(shuō), 應(yīng)使用類引用.
在程序中, 需要先根據(jù)對(duì)象類型聲明引用類型變量, 然后對(duì)該變量引用ABAP對(duì)象, 該引用變量中實(shí)際上存儲(chǔ)的是ABAP對(duì)象的內(nèi)在地址,?
因而該引用類型變量也就是普通意義上的指向?qū)ο蟮闹羔?一個(gè)引用類型變量可以不指向任何內(nèi)存地址或指向一個(gè)數(shù)據(jù)對(duì)象,?
但一個(gè)ABAP對(duì)象則可以同時(shí)存在多個(gè)指向它的指針, 可以通過(guò)所有這些指針對(duì)其進(jìn)行操作.
? DATA ob_vehicle TYPE REF TO vehicle.
? CREATEOBJECT ob_vehicle.
其中DATA語(yǔ)句創(chuàng)建了一個(gè)引用數(shù)據(jù)對(duì)象ob_vehicle?, 該數(shù)據(jù)對(duì)象的類型定義為"指向一個(gè)類為vehicle的對(duì)象的指針".
定義指針之后,CREATE OBJECT 語(yǔ)句則創(chuàng)建了一個(gè)類vehicle的實(shí)例, 并同時(shí)將該對(duì)象的地址指針賦給引用類型ob_vehicle.實(shí)際情況如下圖所示:
引用類型與其它類型的數(shù)據(jù)類型相同, 同類型變量之間也可以相互賦值, 成功賦值之后二者將指向相同的對(duì)象.
?
2. 訪問(wèn)對(duì)象組件.
對(duì)象創(chuàng)建之后, 可以通過(guò)指向它的指針(引用變量)對(duì)其進(jìn)行操作. 可以使用的對(duì)象組件一般為當(dāng)前可見的屬性和方法,?
通過(guò)引用變量后接運(yùn)算符 -> 訪問(wèn)對(duì)象組件. -> 即可以訪問(wèn)類中定義的實(shí)例組件又可以訪問(wèn)靜態(tài)組件.?
但對(duì)于靜態(tài)組件還有另一種訪問(wèn)方式, 通過(guò)類名稱本身=>直接訪問(wèn).
oref->comp
其中oref代表引用變量, comp 代表類成員.
class=>comp
其中class代表類名.
由于引用類型變量本身也可以被定義為類屬性, 因而可以出現(xiàn)下述的鏈?zhǔn)皆L問(wèn)結(jié)構(gòu):
oref1->oref2->comp
或者
class=>oref->comp
上述的兩種運(yùn)算符是類的外部訪問(wèn), 在某些情況下, 對(duì)象本身需要知道本身的地址, 可以使用局部引用變量 ME,
該變量隱式的存在于所有的實(shí)例方法中, 當(dāng)方法被調(diào)用時(shí), 該變量將包含自身的地址指針, 這種用法稱為對(duì)象的自身引用.
3. 刪除對(duì)象
對(duì)象占據(jù)程序內(nèi)存, 如果有后續(xù)程序中不再使用的對(duì)象, 應(yīng)該將其刪除,?
系統(tǒng)對(duì)象的刪除操作與引用變量有關(guān), 系統(tǒng)將自動(dòng)定時(shí)進(jìn)行檢測(cè), 如果一個(gè)對(duì)象不再被任何變量引用, 則將其刪除, 并釋放其所占的內(nèi)存,?
這個(gè)操作是通過(guò)垃圾回收機(jī)制來(lái)完成的.
垃圾回收機(jī)制定時(shí)的清除不再使用的對(duì)象, 使用 CLEAR 語(yǔ)句初始化所有指向該對(duì)象的引用變量或者將引用變量的值改變, 都將觸發(fā)回收機(jī)制.
?
四. 方法.
1. 參數(shù)的定義和傳遞.
類方法的參數(shù)接口部分在在類聲明部分通過(guò)METHODS語(yǔ)句定義的, 而且該接口不需要在類的實(shí)現(xiàn)部分再次出現(xiàn), 參數(shù)接口的詳細(xì)語(yǔ)法形式為:
??? METHODSmeth
?????IMPORTING ... [VALUE(i1)|i1] TYPE type [OPTIONAL|DEFAULT def1] ...
?????EXPORTING ... [VALUE(e1)|e1] TYPE type [OPTIONAL] ...
?????CHANGE??? ... [VALUE(c1)|c1] TYPEtype [OPTIONAL|DEFAULT def1] ...
?????RETURNING VALUE(r)
?????EXCEPTIONS ... X1 ...
?
2. 調(diào)用方法時(shí), 除去指定為可選的參數(shù)之外, 所有的參數(shù)都必須傳遞相應(yīng)的實(shí)參值.
? CALLMETHOD [oref->|class=>]meth
?? EXPORTING...? i1 = f1 ...
???????IMPORTING ...? e1 = g1 ...
???????CHANGING? ...? c1 = c1 ...
???????RECEIVING????? r = h
???????EXCEPTIONS ... x1 = rc1 ...
該語(yǔ)句格式適用于包括類內(nèi)部直接調(diào)用, 實(shí)例調(diào)用(oref->)和靜態(tài)調(diào)用(class=>)三種情況. 其中參數(shù)定義時(shí)用IMPORTING選項(xiàng)指定的形參 i 此時(shí)將接受 CALL METHOD 語(yǔ)句中用EXPORTING 中傳遞的實(shí)參 f; 而用EXPORTING 選項(xiàng)指定的形參 e 此時(shí)將通過(guò) IMPORTING 選項(xiàng)傳遞給實(shí)參 g.
如果方法中只包含輸入?yún)?shù), 而沒有輸出參數(shù), 則可以使用下列幾種形式的簡(jiǎn)略形式對(duì)參數(shù)進(jìn)行調(diào)用.
CALL METHOD [oref->|class=>]method().
CALL METHOD [oref->|class=>]method(f).
CALL METHOD [oref->|class=>|method(...i1 = f1...).
?
Example:
CLASS?VEHICLE?DEFINITION.??PUBLIC?SECTION.
????CLASS-DATA?CLASS_NAME(10)?TYPE?C?VALUE?'Vehicle'.
????METHODS:SHOW_SPEED,
??????ACCELERATE?IMPORTING?RATE?TYPE?I.
??PRIVATE?SECTION.
????DATA?SPEED?TYPE?I.
ENDCLASS.
CLASS?VEHICLE?IMPLEMENTATION.
??METHOD?ACCELERATE.
????SPEED?=?SPEED?+?RATE.
??ENDMETHOD.
??METHOD?SHOW_SPEED.
????WRITE:??/?'Speed:?',?SPEED.
??ENDMETHOD.
ENDCLASS.
DATA:?OB_VEH?TYPE?REF?TO?VEHICLE.
START-OF-SELECTION.
??CREATE?OBJECT?OB_VEH.
??CALL?METHOD?OB_VEH->ACCELERATE?EXPORTING?RATE?=?2.
??CALL?METHOD?OB_VEH->ACCELERATE?EXPORTING?RATE?=?2.
??CALL?METHOD?OB_VEH->SHOW_SPEED.
?
方法還可以進(jìn)行動(dòng)態(tài)調(diào)用, 即通過(guò)變量對(duì)方法名進(jìn)行指定, 例如下列語(yǔ)句:
? meth = accelerate.
? CALL METHOD ob_veh->(meth).
?
實(shí)參的動(dòng)態(tài)傳遞:
? CALL METHOD [oref->|class=>]meth
???PARAMETER-TABLE ptab
???EXCEPTION-TABLE etab.
其中實(shí)參必須在程序中放置在兩個(gè)特定類型的內(nèi)表中, 傳遞給方法, 其中參數(shù)表ptab可以參照類型組ABAP_PARMBID(行類型)和ABAP_PARMBIND_TAB(表類型)生成;?
異常表etab 可以參照ABAP_EXCBIND(行類型)和ABAP_EXCBIND_TAB(表類型)生成.
?
3. 函數(shù)方法.
函數(shù)也是一種過(guò)程模塊, 其特殊之處是在調(diào)用時(shí)可以使用操作符(=)來(lái)替代過(guò)程調(diào)用語(yǔ)句, 并可作為操作數(shù)直接應(yīng)用于操作語(yǔ)句中, 因?yàn)楹瘮?shù)只返回一個(gè)唯一的值.?
在ABAP Objects 語(yǔ)法中, 可以用例如函數(shù)方法來(lái)實(shí)現(xiàn)這種函數(shù)功能, 形式如下:
??? METHODSmeth
????? IMPORTING... [ VALUE(i1)|i1] TYPE type [OPTIONAL|DEFAULT def1] ...
?????RETURNING VALUE(r).
一個(gè)函數(shù)方法可以有多個(gè)數(shù)量的輸入?yún)?shù), 但只能有一個(gè)輸出參數(shù), 且該輸出參數(shù)必須為值傳遞而且需要完成限定其類型.
函數(shù)方法的調(diào)用格式如下:
CALL METHOD [oref->|class=>]meth
? EXPORTING... i1 = f1 ...
?RECEIVING???? r = h.
簡(jiǎn)化的調(diào)用形式如下:
... [oref->|class=>]method( ) ...
... [oref->|class=>]method(f) ...
... [oref->|class=>]method(... i1 = f1 ...)...
?
CLASS?CIRCLE?DEFINITION.??PUBLIC?SECTION.
????METHODS?GET_AREA?IMPORTING?VALUE(I_RADIUS)?TYPE?I
?????????????????????RETURNING?VALUE(R_SIZE)???TYPE?F.
??PRIVATE?SECTION.
????CONSTANTS?PI?TYPE?F?VALUE?'3.1415926'.
ENDCLASS.
CLASS?CIRCLE?IMPLEMENTATION.
??METHOD?GET_AREA.
????R_SIZE?=?I_RADIUS?**?2?*?PI.
??ENDMETHOD.
ENDCLASS.
DATA:?OB_CIRCLE?TYPE?REF?TO?CIRCLE,
??????AREA??????TYPE?F.
PARAMETERS:?RADIUS?TYPE?I.
START-OF-SELECTION.
??CALL?METHOD?OB_CIRCLE->GET_AREA
????EXPORTING
??????I_RADIUS?=?RADIUS
????RECEIVING
??????R_SIZE???=?AREA.
??WRITE:?/?AREA.
??AREA?=?OB_CIRCLE->GET_AREA(?RADIUS?).
??WRITE:?/?AREA.
?
4. 構(gòu)造和析構(gòu)方法.
1). 構(gòu)造方法是運(yùn)行時(shí)環(huán)境自動(dòng)調(diào)用的一種方法, 用于為對(duì)象設(shè)定一個(gè)初始化狀態(tài), 不能在程序運(yùn)行過(guò)程中由程序代碼調(diào)用.?
實(shí)例構(gòu)造方法在每一次對(duì)象創(chuàng)建的過(guò)程中(CREATE OBJECT語(yǔ)句時(shí))被系統(tǒng)調(diào)用, 如果在類聲明部分進(jìn)行聲明, 則需要在實(shí)現(xiàn)部分進(jìn)行代碼實(shí)現(xiàn).
METHODS constructor
? IMPORTING... [VALUE(i1)|i1] TYPE type [OPTIONAL|DEFAULT def1] ...
? EXCEPTIONS... e1 ...
構(gòu)造方法中不包含任何形式的輸出參數(shù), 其功能只是定義對(duì)象狀態(tài), 而不是對(duì)其進(jìn)行改變.
類構(gòu)造方法屬于靜態(tài)方法, 只在程序中被調(diào)用一次, 即第一次使用該類時(shí)調(diào)用,?
該方法也必須在公有部分聲明, 其名稱必須為 CLASS_CONSTRUCTOR.
???CLASS-METHODS class_constructor.
類構(gòu)造方法不包含接口, 而且在其中只能訪問(wèn)類的靜態(tài)屬性.
?
CLASS?VEHICLE?DEFINITION.??PUBLIC?SECTION.
????CLASS-DATA?CLASS_NAME(10)?TYPE?C?VALUE?'Vehicle'.
????METHODS:SHOW_SPEED,
??????ACCELERATE?IMPORTING?RATE?TYPE?I,
??????CONSTRUCTOR?IMPORTING?I_SPEED?TYPE?I.?"構(gòu)造函數(shù)
??PRIVATE?SECTION.
????DATA?SPEED?TYPE?I?VALUE?0.
ENDCLASS.
CLASS?VEHICLE?IMPLEMENTATION.
??METHOD?CONSTRUCTOR.
????SPEED?=?I_SPEED.
??ENDMETHOD.
??METHOD?ACCELERATE.
????SPEED?=?SPEED?+?RATE.
??ENDMETHOD.
??METHOD?SHOW_SPEED.
????WRITE:??/?'Speed:?',?SPEED.
??ENDMETHOD.
ENDCLASS.
DATA:?OB_VEH?TYPE?REF?TO?VEHICLE.
START-OF-SELECTION.
??CREATE?OBJECT?OB_VEH?EXPORTING?I_SPEED?=?4.?"構(gòu)造函數(shù)
??CALL?METHOD?OB_VEH->SHOW_SPEED.
??CALL?METHOD?OB_VEH->ACCELERATE
????EXPORTING
??????RATE?=?2.
??CALL?METHOD?OB_VEH->ACCELERATE
????EXPORTING
??????RATE?=?2.
??CALL?METHOD?OB_VEH->SHOW_SPEED.
?
五. 繼承
ABAP 所有的類都是默認(rèn)繼承了系統(tǒng)中的空類OBJECT.
具有一般性的類稱為基類(Superclass),其各個(gè)子類稱為派生類(Subclass).
在類定義時(shí), 使用 INHERTING FROM 附加項(xiàng)可以指定派生類和基類之間的繼承關(guān)系.
CLASS c2 DEFINITION INHERITING FROM c1.
? ...
ENDCLASS.
ABAP 中的繼承為單一繼承, 即一個(gè)類可以有多個(gè)派生類, 但只能有一個(gè)直接基類.
在繼承過(guò)程中各成員的組件可見性如下:
一個(gè)派生類中的公有成員包括其本身公有部分定義的成員以及所有基類公有成員, 這些公有成員可以通過(guò)選擇運(yùn)算符"->" 在類外部獲得.
一個(gè)派生類中的被保護(hù)成員包括其本身被保護(hù)部分定義的成員以及所有基類的被保護(hù)成員.?
這些成員不能通過(guò)組件選擇運(yùn)算符"->" 在類外部獲得, 但可以在派生類內(nèi)部使用. 在類外部看, 其行為與類私有成員完全一致.
一個(gè)派生類中的私有成員只包括其本身私有部分定義的成員. 這些成員只能在派生類內(nèi)部使用.
因而, 繼承類和基類的公有成員和被保護(hù)成員享有共同的命名空間, 而私有成員則在不同類之間可以出現(xiàn)重名情況.
參照基類聲明的引用變量可以指向其繼承類的對(duì)象, 如上圖所示,?
對(duì)象 n 是類 Class3的一個(gè)實(shí)例, 而左側(cè)的三個(gè)引用變量CREF1, CREF2, CREF3 則分別參數(shù)類Class1, Class2, Class3 生成.?
這三個(gè)類存在繼承關(guān)系. 參考基類聲明的引用變量也可以指向其派生類, 即三個(gè)變量均可以指向?qū)ο?n,?
但要注意的是 CREF1 只能訪問(wèn) Class1 的公有組件, 而 CREF2可以訪問(wèn) Class1 和 Class2的公有組件, CREF3 則可以訪問(wèn)全部類的公有組件.
但特別要注意的是: 盡管基類引用變量可以指向其繼承類對(duì)象, 然而反之則被視為錯(cuò)誤的類型轉(zhuǎn)換.
?
多態(tài)性的繼承實(shí)現(xiàn).
在繼承中, 多態(tài)性是通過(guò)方法重載及引用變量實(shí)現(xiàn)的, 即子類可以重新定義并以不同的方式實(shí)現(xiàn)基類中的公有或保護(hù)方法, 此時(shí)基類中的方法需為實(shí)例方法.
在派生類中要這樣聲明:
METHOD meth REDEFINITION.
該方法必須和基類中的方法具有相同的接口, 但可以通過(guò)不同的代碼實(shí)現(xiàn).
在方法重載過(guò)程中, 如果在派生類內(nèi)部仍然需要使用基類中的方法, 則可以使用 SUPER 關(guān)鍵字來(lái)指定其基類.
CALL METHOD?super->meth.
Example:
*&---------------------------------------------------------------------*
*& Report?Z_AF_050
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*
?
REPORT?z_af_050.
?
CLASS class1 DEFINITION INHERITING FROMobject.???? "基類
? PUBLICSECTION.
??? METHODS:accelerate,
????????????write_status.
? PROTECTEDSECTION.
??? DATA:speed TYPE i.
ENDCLASS.
?
CLASS plane DEFINITION INHERITING FROM class1.
? PUBLICSECTION.
??? METHODS:rise,
????????????write_status REDEFINITION.??? ????????"多態(tài)
? PROTECTEDSECTION.
??? DATAaltitude TYPE i.
ENDCLASS.
?
CLASS ship DEFINITION INHERITING FROM class1.
? PUBLICSECTION.
??? METHODS:write_status REDEFINITION.???????????"多態(tài)
ENDCLASS.
?
CLASS class1 IMPLEMENTATION.
? METHODaccelerate.
??? speed =speed + 1.
? ENDMETHOD.
? METHODwrite_status.
??? WRITE: /'Speed:', speed.
? ENDMETHOD.
ENDCLASS.
?
CLASS plane IMPLEMENTATION.
? METHODrise.
??? altitude= altitude + 2.
? ENDMETHOD.
? METHODwrite_status.
???WRITE:? 'Plane:'.
??? CALLMETHOD super->write_status.
??? WRITE: /'Altitude:', altitude.
? ENDMETHOD.
ENDCLASS.
?
CLASS ship IMPLEMENTATION.
? METHODwrite_status.
??? WRITE: /'Ship speed:', speed.
? ENDMETHOD.
ENDCLASS.
?
DATA: plane_ref TYPE REF TO plane.
DATA: ship_ref TYPE REF TO ship.
?
START-OF-SELECTION.
? CREATEOBJECT: plane_ref,
????????????????ship_ref.
? CALLMETHOD: plane_ref->accelerate,
??????????????plane_ref->rise,
??????????????plane_ref->write_status,
??????????????ship_ref->accelerate,
??????????????ship_ref->write_status.
?
抽象類和抽象方法.
一個(gè)基類可能包含多個(gè)派生類, 但該基類只是作為模板出現(xiàn)的, 并不需要有任何對(duì)象作為實(shí)例, 則可以將該類聲明為抽象類(Abstract Class).
CLASS class1 DEFINITION ABSTRACT.
...
ENDCLASS.
抽象類不能使用CREATE OBJECT 語(yǔ)句創(chuàng)建類對(duì)象, 其主要目的是為了做派生類的模板, 實(shí)際使用的對(duì)象則依照各個(gè)派生類創(chuàng)建.
也可以將方法定義為抽象方法.
METHODS meth ABSTRACT ...
一個(gè)抽象方法不能在類本身中實(shí)現(xiàn), 而必須在其派生出的非抽象類中實(shí)現(xiàn). 因而含有抽象方法的類必須定義為抽象類.
?
最終類和最終方法.
最終類(FinalClass), 是不能被繼承的類, 其主要意義在于: 設(shè)計(jì)過(guò)程中, 如果一個(gè)類有很多級(jí)別的派生類, 則其中公有和被保護(hù)成員方法, 隨意改動(dòng)該類, 很容易造成派生類中的語(yǔ)法和主義沖突. 因而, 如果不希望在程序中繼續(xù)對(duì)該類進(jìn)行派生, 則可以定義該類為最終類.
CLASS class1 DEFINITION FINAL.
...
ENDCLASS.
最終方法是不可以重新定義的方法, 不一定出現(xiàn)在最終類中, 但最終類中的所有方法都是最終方法.
METHODS meth ABSTRACT ...
?
六. 接口.
1. 接口的定義與實(shí)現(xiàn).
Interfaces 即可以保證這些類外部看起來(lái)具胡一致性,標(biāo)準(zhǔn)化的接口, 又可以在不同的類內(nèi)部使用不同的實(shí)現(xiàn)方法, 而這個(gè)具體實(shí)現(xiàn)過(guò)程是類外部的用戶無(wú)需關(guān)心的.
接口是一個(gè)獨(dú)立結(jié)構(gòu), 可以在其中定義一些成員并在具體類中實(shí)現(xiàn), 其作用是對(duì)類中已經(jīng)定義的成員進(jìn)行擴(kuò)展. 實(shí)現(xiàn)接口后,接口將成為類的公有成員, 但類可以自行對(duì)接口中的方法以其自身特定形式實(shí)現(xiàn). 這樣, 對(duì)于用戶來(lái)說(shuō), 不同的類對(duì)象包含相同的操作接口(即接口中定義的成員名稱), 但程序內(nèi)部的具體實(shí)現(xiàn)則根據(jù)類的不同而有所區(qū)別. 接口是OOP中除繼承之外的另一個(gè)主要多態(tài)性的實(shí)現(xiàn)機(jī)制技術(shù).
?
在程序中定義接口.
INTERFACE intf.
? DATA ...
? CLASS-DATA...
? METHOD ...
? ...
ENDINTERFACE.
在接口定義內(nèi)部可以聲明的成員與類中的成員相同, 但無(wú)需注明具體的可見性, 因?yàn)榫唧w類中實(shí)現(xiàn)的所有接口組件均為公有成員. 同時(shí), 接口定義中也只包含成員聲明部分, 而具體的實(shí)現(xiàn)也將在具體類中進(jìn)行.
?
實(shí)現(xiàn)接口.
接口沒有自己的實(shí)例, 因而也不需要進(jìn)行方法實(shí)現(xiàn), 其中方法的實(shí)現(xiàn)要通過(guò)具體的類進(jìn)行.
語(yǔ)法格式如下:
CLASS class1 DEFINITION.
? PUBLICSECTION.
??? ...
???INTERFACES: int1, int2.
? ...
ENDCLASS.
在類定義中, 接口的實(shí)現(xiàn)只能出現(xiàn)在公有部分, 接口中定義的所有組件都將被添加為該類的公有成員.
接口中的成員通過(guò)接口名稱 +" ~ " + 成員方式訪問(wèn).intf~comp.
在類的實(shí)現(xiàn)部分, 必須包含所有的接口方法實(shí)現(xiàn).
CLASS class IMPLEMENTATION.
? ...
? METHODintf1_imeth1.
??? ...
? ENDMETHOD.
??? ...
? METHODintf2_imeth2.
??? ...
? ENDMETHOD.
? ...
ENDCLASS.
一個(gè)接口可以被任意多個(gè)不同的類實(shí)現(xiàn), 該接口中定義的成員集在各個(gè)類中名稱相同(形成了一個(gè)標(biāo)準(zhǔn)接口), 然而各個(gè)類中成員的方法的實(shí)現(xiàn)方式則可以有差異, 也就形成了多態(tài)性. 如果一個(gè)類中除接口之外沒有定義任何類自身的公有成員方法, 則接口就成了該類中的全部"外部接口".
?
*&---------------------------------------------------------------------*
*& Report?Z_AF_051
*&
*&---------------------------------------------------------------------*
?
REPORT?z_af_051.
?
INTERFACE status.???? " Define a interface
? METHODSwrite.
ENDINTERFACE.
?
CLASS counter DEFINITION.
? PUBLICSECTION.
???INTERFACES status.
??? METHODSincrement.
? PRIVATESECTION.
??? DATAcount TYPE i.
ENDCLASS.
?
CLASS counter IMPLEMENTATION.
? METHOD status~write.?????????? " 在接口的實(shí)現(xiàn)部分以 stauts~write 實(shí)現(xiàn).
??? WRITE: /'Count in counter is ', count.
? ENDMETHOD.
? METHODincrement.
??? ADD 1 TOcount.
? ENDMETHOD.
ENDCLASS.
?
CLASS bicycle DEFINITION.
? PUBLICSECTION.
???INTERFACES status.
??? METHODSdrive.
? PRIVATESECTION.
??? DATAspeed TYPE i.
ENDCLASS.
?
CLASS bicycle IMPLEMENTATION.
? METHODstatus~write.
??? WRITE: /'Speed of bicycle is', speed.
? ENDMETHOD.
? METHODdrive.
??? ADD 10 TOspeed.
? ENDMETHOD.
ENDCLASS.
?
DATA: count TYPE REF TO counter,
????? bikeTYPE REF TO bicycle,
????? statusTYPE REF TO status,
?????status_tab TYPE TABLE OF REF TO status.
?
START-OF-SELECTION.
? CREATEOBJECT: count, bike.
? DO 5 TIMES.
??? CALLMETHOD: count->increment,
????????????????bike->drive.
? ENDDO.
?
? APPEND:count TO status_tab,
?????????bike TO status_tab.
?
? LOOP ATstatus_tab INTO status.
??? CALLMETHOD status->write.
? ENDLOOP.
該例中包含兩個(gè)完全無(wú)關(guān)的類 bike 和 count, 但實(shí)現(xiàn)了相同的接口 status, 因而這兩個(gè)類都包含同樣的方法 write, 該方法是在接口中定義的.
?
接口引用.
引用變量是訪問(wèn) ABAP 對(duì)象的途徑, 與基于類聲明的引用變量類似, 也可以基于接口聲明引用變量, 即接口引用. 接口引用也是一種對(duì)象引用, 對(duì)于包含接口的類對(duì)象, 除通過(guò)類引用訪問(wèn)之外, 還可通過(guò)接口引用進(jìn)行訪問(wèn). 接口引用可以指向任何實(shí)現(xiàn)了該接口的對(duì)象.
YPTES|DATA iref TYPE REF TO intf.
其中 intf 是全局或程序中已經(jīng)定義的接口.
?
通過(guò)接口引用訪問(wèn)對(duì)象.
要訪問(wèn)一個(gè)類對(duì)象, 必須先聲明一個(gè)基于該類的引用變量, 如果該類為一個(gè)接口的實(shí)現(xiàn), 則可以將該車胎變量賦給一個(gè)接口變量, 此時(shí)接口引用與類引用指向相同的類對(duì)象.
假設(shè)接口變量名稱為 inef,類引用名稱為 cref, 賦值語(yǔ)法格式如下:
iref = cref.
使用類引用訪問(wèn):
cref->intf~attr.
CALL METHOD cref->intf~meth.
使用接口引用訪問(wèn)屬性和方法的語(yǔ)法格式如下:
iref->attr.
CALL METHOD iref->meth.
對(duì)于接口中定義的靜態(tài)成員, 如果該成員是常量, 則只能通過(guò)接口引用進(jìn)行訪問(wèn):
intf=>const
對(duì)于其他靜態(tài)接口成員, 則可以通過(guò)實(shí)現(xiàn)該接口的類本身或者類引用進(jìn)行訪問(wèn):
class=>intf~attr.
CALL METHOD class=>intf~meth.
?
在接口引用間賦值.
與類引用類似, 可以將接口引用分配給不同的引用變量, 還可以在類引用和接口引用之間相互賦值.
假設(shè)存在類引用 cref 和接口引用iref, iref1 和 iref2.
iref1 = iref2.
系統(tǒng)將進(jìn)行靜態(tài)語(yǔ)法檢查, 這兩個(gè)接口必須參照同一個(gè)接口聲明, 或者 iref2 所參照的接口是接口 iref1 的一個(gè)成員.
如果使用形式:
iref = cref.
則 cref 參照的類必須是 ABAP 預(yù)定義的空類 OBJECT.
對(duì)于所有其他情況, 則必須通過(guò)強(qiáng)制賦值語(yǔ)句或者強(qiáng)制賦值運(yùn)算符 "?="進(jìn)行.
MOVE iref to cref.
cref ?= iref.
在進(jìn)行強(qiáng)制賦值時(shí), 系統(tǒng)不會(huì)出現(xiàn)任何靜態(tài)語(yǔ)法檢查, 但系統(tǒng)將在運(yùn)行時(shí)檢查目標(biāo)對(duì)象引用變量是否可以指向源變量引用的對(duì)象. 如果允許則進(jìn)行賦值, 否則將觸發(fā)可以捕獲的運(yùn)行時(shí)錯(cuò)誤MOVE_CASE_ERROR.
如果將接口引用賦給類引用, 且該類不是參照OBJECT聲明,則必須使用強(qiáng)制賦值, 要使賦值過(guò)程成功, 接口引用 iref所指向的對(duì)象中必須與類引用cref參照的類相同.
?
七 事件.
事件是除去屬性, 方法之外的第三類成員. 這三種組件中, 屬性用于刻畫類對(duì)象的狀態(tài), 方法用于訪問(wèn)或修改對(duì)象狀態(tài), 而事件則用于一個(gè)類對(duì)象發(fā)布其狀態(tài)的改變, 因而其他對(duì)象可以捕獲該方法并作出響應(yīng).
在ABAPObject 中, 事件的觸發(fā)和處理是通過(guò)特定的方法進(jìn)行的, 一個(gè)方法作為觸發(fā)者觸發(fā)事件, 而程序中的另一個(gè)方法則作為處理者捕獲并處理該事件, 處理方法在事件出現(xiàn)進(jìn)被執(zhí)行.
?
聲名事件.
事件可以在類或接口的聲名部分進(jìn)行聲明.
EVENTS|CLASS-EVENTS evt
? EXPORTING... VALUE(e1) TYPE type [OPTIONAL] ...
聲明該事件時(shí), 可以使用 EXPORTING 附加項(xiàng)指定需要向事件處理方法中傳遞的參數(shù), 該參數(shù)傳遞方法恒為值傳遞. 實(shí)例事件總是包含一個(gè)隱含的參數(shù) SENDER, 該參數(shù)的類型為觸發(fā)事件的類或接口的對(duì)象引用.
?
觸發(fā)事件.
一個(gè)實(shí)例事件可以被類中的任意方法觸發(fā), 靜態(tài)事件則可以被靜態(tài)方法觸發(fā).
RAISE EVENT evt EXPORTING ... e1 = f1 ...
對(duì)于每一個(gè)沒有被指定OPTIONAL 項(xiàng)的形參 ei, 均必須在實(shí)例方法中傳遞一個(gè)實(shí)參 fi, 自身引用 ME 對(duì)象在被默認(rèn)的傳遞到隱含參數(shù) SENDER.
?
事件處理方法
事件需要通過(guò)方法捕獲事件并進(jìn)行處理, 必須首先為該事件定義一個(gè)事件處理方法, 然后在運(yùn)行時(shí)為該事件進(jìn)行注冊(cè).
聲明事件處理方法
任何類都可以為其它類中定義的事件進(jìn)行處理, 同時(shí)也可以為自身事件進(jìn)行處理.
實(shí)例事件處理方法的語(yǔ)法格式如下:
METHODS|CLASS-METHODS
? meth FOREVENT evt OF cif IMPORTING ... ei ...
一個(gè)事件處理方法的接口中只能包含定義在事件 evt 中的形式參數(shù), 并需遵循事件中的參數(shù)屬性設(shè)定, 但事件處理方法不需要使用所有 RAISE EVENT 中定義的參數(shù).
?
注冊(cè)事件處理方法.
要使事件處理方法能夠?qū)κ录M(jìn)行響應(yīng),必須在運(yùn)行時(shí)為相關(guān)事件注冊(cè)該方法, 語(yǔ)法格式如下:
SET HANDLER ... hi ... [FOR] ...
該語(yǔ)句將處理方法和相關(guān)的觸發(fā)方法進(jìn)行鏈接, 其語(yǔ)法和使用效果部分地取決于事件的類型.
定義在類中的實(shí)例事件.
定義在接口中的實(shí)例事件.
定義在類中的靜態(tài)事件.
定義在接口中的靜態(tài)事件.
對(duì)于實(shí)例事件, 在進(jìn)行處理之前必須在注冊(cè)語(yǔ)句中使用附加項(xiàng) FOR 指定希望注冊(cè)到的對(duì)象.
可以指定一個(gè)單獨(dú)的對(duì)象作為事件觸發(fā)者.
SET HANDLER ... hi ... FOR ref.
或者使用 FORALL INSTANCES 附加項(xiàng)為處理器注冊(cè)所有可以觸發(fā)該事件的實(shí)例;
SET HANDLER ... hi ... FOR ALL INSTANCES.
該注冊(cè)過(guò)程可以作用于目前尚未被創(chuàng)建的實(shí)例.
對(duì)于靜態(tài)事件, 則不能使用 FOR 附加項(xiàng);
SET HANDLER ... hi ...
該注冊(cè)自動(dòng)應(yīng)用于整個(gè)類, 對(duì)于接口中的靜態(tài)事件, 該注冊(cè)可以應(yīng)用于目前尚未裝載至內(nèi)在中的類.
?
事件處理時(shí)間.
在程序執(zhí)行到 RAISEEVENT 語(yǔ)句之后, 所有已注冊(cè)的處理方法都將在下一個(gè)語(yǔ)句之前被處理. 如果處理方法本身觸發(fā)事件, 則該處理方法在原方法繼續(xù)執(zhí)行之前被重新調(diào)用.
?
事件的觸發(fā)及處理.
事件的觸發(fā)和處理基本過(guò)程如下: 假設(shè)有兩個(gè)類 C1 和 C2, C1中包含事件 E1, 而該事件可能在方法 M1 中通過(guò) RAISE EVENT 語(yǔ)句被觸發(fā), 而 C2 中將包含方法 M2, 該方法可以捕獲事件 E1, 并進(jìn)行處理.
在實(shí)際操作時(shí), 要使一個(gè)對(duì)象的事件處理方法能夠捕獲另一個(gè)對(duì)象觸發(fā)事件, 必須先使用 SET HANDLER 語(yǔ)句進(jìn)行注冊(cè), 這個(gè)注冊(cè)過(guò)程中形成了觸發(fā)對(duì)象和響應(yīng)對(duì)象之間的對(duì)應(yīng)關(guān)系.
當(dāng)然, 也可以同時(shí)注冊(cè)多個(gè)處理對(duì)象與一個(gè)觸發(fā)對(duì)象相對(duì)應(yīng).
SET HANDLER 語(yǔ)句則創(chuàng)建一個(gè)系統(tǒng)內(nèi)部的事件處理表, 為每一個(gè)事件注冊(cè)相應(yīng)的方法. 該表為系統(tǒng)隱含. 對(duì)于實(shí)例事件, 事件處理表中包含用于實(shí)現(xiàn)處理的方法名稱以及注冊(cè)了的類實(shí)例引用, 該表通過(guò) SET HANDLER 語(yǔ)句動(dòng)態(tài)的進(jìn)行維護(hù). 對(duì)于靜態(tài)事件, 系統(tǒng)為相關(guān)類創(chuàng)建一個(gè)實(shí)例無(wú)關(guān)的處理表. 一旦事件被觸發(fā), 系統(tǒng)將查找相關(guān)的事件表并執(zhí)行對(duì)應(yīng)于該事件的實(shí)例方法.
?
*&---------------------------------------------------------------------*
*& Report?Z_AF_052
*&
*&---------------------------------------------------------------------*
?
REPORT?z_af_052.
?
CLASS class1 DEFINITION INHERITING FROM object.
? PUBLICSECTION.
??? EVENTS:too_fast.??????????? " 聲明事件,如果有參數(shù)恒為值傳遞
??? METHODS:accelerate,
????????????show_speed.
? PROTECTEDSECTION.
??? DATA:speed TYPE i.
ENDCLASS.
?
CLASS class1 IMPLEMENTATION.
? METHODaccelerate.
??? speed =speed + 1.
??? IF speed> 5.
????? RAISEEVENT too_fast.???? "觸發(fā)事件
????? speed =5.
??? ENDIF.
? ENDMETHOD.
? METHODshow_speed.
??? WRITE: /'Speed:', speed.
? ENDMETHOD.
ENDCLASS.
?
*事件需要通過(guò)方法捕獲事件并進(jìn)行處理,必須首先為該事件定義
*一個(gè)事件處理方法,然后在運(yùn)行時(shí)為該事件進(jìn)行注冊(cè).
*聲明事件處理方法,任何類都可以為其他類中定義的事件進(jìn)行處理,
*當(dāng)然也可以為自身事件進(jìn)行處理.
CLASS handler DEFINITION.
? PUBLICSECTION.?????????
??? METHODShandle_excess FOR EVENT too_fast OF class1.
ENDCLASS.
?
CLASS handler IMPLEMENTATION.
? METHOD handle_excess.
??? WRITE: /'Speed can not be too fast.'.
? ENDMETHOD.
ENDCLASS.
?
DATA: o_class1 TYPE REF TO class1,
?????o_handle TYPE REF TO handler.
?
START-OF-SELECTION.
? CREATEOBJECT: o_class1,
????????????????o_handle.
*要使事件處理方法能夠?qū)κ录M(jìn)行響應(yīng),? 必須在運(yùn)行時(shí)為相關(guān)事件注冊(cè)該方法.
? SET HANDLERo_handle->handle_excess FOR ALL INSTANCES.
?
? DO 11TIMES.
??? CALLMETHOD o_class1->accelerate.
??? CALLMETHOD o_class1->show_speed.
? ENDDO.
總結(jié)
以上是生活随笔為你收集整理的ABAP面向对象的开发的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ABAP-DOI技术的优化
- 下一篇: vbe6ext.olb不能被加载解决方案