ABAP面向对象
2.面向對象
2.1.??類與接口定義
CLASS?class?DEFINITION?[ABSTRACT][FINAL].?
??[PUBLIC?SECTION.?
????[components]]?
??[PROTECTED?SECTION.?
????[components]]?
??[PRIVATE?SECTION.?
????[components]]?
ENDCLASS.?
INTERFACE?intf.?
??[components]?
ENDINTERFACE.?
2.1.1.???components
2TYPES,?DATA, CLASS-DATA, CONSTANTS??for data types and data objects
2METHODS, CLASS-METHODS,?EVENTS, CLASS-EVENTS?for methods and events
2??INTERFACES(如果在類中,表示需要實現哪個接口;如果是在接口中,表示繼承哪個接口)?for implementing interfaces
2??ALIASESfor alias names for interface components給接口組件取別名
2.2.類定義、實現
CLASS?math?DEFINITION.
PUBLIC?SECTION.
METHODS?divide_1_by
IMPORTING?operand?TYPE?i
EXPORTING?result??TYPE?f
RAISING?cx_sy_arithmetic_error.
ENDCLASS.
CLASS?math?IMPLEMENTATION.
METHOD?divide_1_by.
????result?=?1?/?operand.
ENDMETHOD.
ENDCLASS.
2.3.接口定義、實現
INTERFACEint1.
ENDINTERFACE.
CLASSclass?DEFINITION.??????????????????????? [?defi?ni??n]
PUBLICSECTION.
INTERFACES: int1,int2."可實現多個接口
ENDCLASS.
CLASS?class?IMPLEMENTATION.?????????????????????[??mpl?m?n?te?-??n]
METHOD?intf1~imeth1.
ENDMETHOD.
ENDCLASS.
2.4.類、接口繼承
CLASS<subclass>?DEFINITIONINHERITINGFROM<superclass>.[in?herit]
?
INTERFACE?i0.
METHODS?m0.
ENDINTERFACE.
INTERFACE?i1.
INTERFACES?i0.
??"可以有相同的成員名,因為繼承過來后,成員還是具有各自的命名空間,在實現時
"被繼承過來的叫?i0~m0,在這里的名為i1~m0,所以是不同的兩個方法
METHODS?m0.
METHODS?m1.
ENDINTERFACE.
2.5.??向下強轉型??=
CLASS?person?DEFINITION.
ENDCLASS.
CLASS?stud?DEFINITION?INHERITING FROMperson.
ENDCLASS.
?
START-OF-SELECTION.
??DATA?p?TYPE REF TO?person.
? DATA?s?TYPE REF TO?stud.
? CREATE OBJECT?s.
??p?=?s.?"向上自動轉型
??"拿開注釋運行時拋異常,因為P此時指向的對象不是Student,而是Person所以能強轉的前提是P指向的是Student
? "CREATE OBJECT p.
? s??=?p."向下強轉型
2.6.??方法
METHODS/CLASS-METHODS?meth?[ABSTRACT|FINAL]?
????[IMPORTING?parameters?[PREFERRED?PARAMETER?p]]?
????[EXPORTING?parameters]?
????[CHANGING?parameters]?
????[{RAISING|EXCEPTIONS}?exc1?exc2?...].
應該還有一個Returning選項,且RETURNING不能與EXPORTING、CHANGING同時使用:
2.6.1.parameters
...?{?VALUE(p1) |?REFERENCE(p1) | p1 }
{?TYPE?generic_type?}
|{TYPE{[LINE OF]?complete_type}|{REF TO?{data|object|complete_type?|class|intf}}}
|{LIKE{[LINE OF] dobj}|{REF TO?dobj}?}?
[OPTIONAL|{DEFAULT?def1}]
???? {?VALUE(p2) |?REFERENCE(p2) | p2 }...
2data、object:表示是通用數據類型data、object
2complete_type:為完全限定類型
2OPTIONAL與DEFAULT兩個選項不能同時使用,且對于EXPORTING類型的輸入參數不能使用
2如果參數名p1前沒有使用VALUE、REFERENCE,則默認為還是REFERENCE,即引用傳遞
2方法中的輸入輸出參數是否能修改,請參考Form、Function參數的傳值傳址
2.6.2.???PREFERRED PARAMETER首選參數
設置多個IMPORTING類型參數中的某一個參數為首選參數。
首選參數的意義在于:當所有IMPORTING類型都為可選optional時,我們可以通過PREFERRED PARAMETER選項來指定某一個可選輸入參數為首選參數,則在以下簡單方式調用時:[CALL?METHOD]?meth(?a?).?實參a的值就會傳遞給設置的首選參數,而其他不是首參數的可選輸入參數則留空或使用DEFAULT設置的默認值
注:此選項只能用于IMPORTING類型的參數;如果有必選的IMPORTING輸入參數,則沒有意義了
2.6.3.???普通調用
[CALL METHOD]? meth|me->meth|oref->meth|super->meth|class=>meth[(]
[EXPORTING? p1 = a1 p2 = a2 ...]
{?{[IMPORTING? p1=a1 p2=a2 ...][CHANGING?p1 = a1 p2 = a2 ...]}
|[RECEIVING? r? = a? ]?}?RECEIVING不能與EXPORTING、CHANGING同時使用
[EXCEPTIONS?[exc1 = n1 exc2 = n2 ...]
[OTHERS?= n_others] ] [)].
如果省略CALL METHOD,則一定要加上括號形式;如果通過CALL METHOD來調用,則括號可加可不加
RECEIVING:用來接收METHODS /CLASS-METHODS?中RETURNING選項返回的值
如果EXPORTING、IMPORTING、CHANGING、RECEIVING、EXCEPTIONS、OTHERS同時出現時,應該按此順序來編寫
注:使用此種方式調用(使用?EXPORTING、IMPORTING等這些選項)時,如果原方法聲明時帶了返回值RETURNING,只能使用RECEIVING來接受,而不能使用等號來接收返回值,下面用法是錯誤的:
num2?=?o1->m1(?EXPORTING?p1?=?num1?).
2.6.4.???簡單調用
此方式下輸入的參數都只能是IMPORTING類型的參數,如果要傳CHANGING、EXPORTING、RAISING、EXCEPTIONS類型的參數時,只能使用上面通用調用方式。
2meth( )
此種方式僅適用于沒有輸入參數(IMPORTING)、輸入\輸出參數(CHANGING)、或者有但都是可選的、或者不是可選時但有默認值也可
2meth( a )
此種方式僅適用于只有一個必選輸入參數(IMPORTING)(如果還有其他輸入參數,則其他都為可選,或者不是可選時但有默認值也可),或者是有多個可選輸入參數(IMPORTING)(此時沒有必選輸入參數情況下)的情況下但方法聲明時通過使用PREFERRED PARAMETER選項指定了其中某個可選參數為首選參數(首選參數即在使用meth( a )方式傳遞一個參數進行調用時,通過實參a傳遞給設置為首選的參數)
2meth( p1 = a1 p2 = a2 ... )
此種方式適用于有多個必選的輸入參數(IMPORTING)方法的調用(其它如CHANGING、EXPORTING沒有,或者有但可選),如果輸入參數(IMPORTING)為可選,則也可以不必傳
2.6.5.函數方法
Return唯一返回值
METHODS?meth
??? [IMPORTING?parameters?[PREFERRED PARAMETER?p]]
????RETURNINGVALUE(r) typing
??? [{RAISING|EXCEPTIONS} exc1 exc2 ...].
?
RETURNING?:用來替換EXPORTING、CHANGING,不能同時使用。定義了一個形式參數?r?來接收返回值,并且只能是值傳遞
具有唯一返回值的函數方法可以直接用在以下語句中:邏輯表達式(IF、ELSEIF、WHILE、CHECK、WAIT)、CASE、LOOP、算術表達式、賦值語句
函數方法可以采用上面簡單調用方式來調用:meth( )、meth( a )、meth( p1 = a1 P2 = a2 ... )
?
??ref->m(?RECEIVING??r?=?i?).
CALL?METHOD?ref->m(?RECEIVING?r?=?i?).
CALL?METHOD?ref->m?RECEIVING?r?=?i.
2.7.me、super
等效于Java中的?this、super
2.8.??事件
2.8.1.???事件定義
EVENTS|CLASS-EVENTS?evt [EXPORTING VALUE(p1)?
{?TYPE?generic_type }?
|{TYPE?{[LINE OF] complete_type}?|
{?REF TO?{data|object|complete_type|class|intf}}?}
| {LIKE{[LINE OF] dobj}?|?{REF TO?dobj}?}?
[OPTIONAL|{DEFAULT?def1}]?
VALUE(p2) ...].
2data、object:表示是通用數據類型data、object
2complete_type:為完全限定類型
2??OPTIONAL與DEFAULT兩個選項不能同時使用
2EXPORTING:定義了事件的輸出參數,并且事件定義時只能有輸出參數,且只能是傳值
?
非靜態事件聲明中除了明確使用EXPORTING定義的輸出外,每個實例事件其實還有一個隱含的輸出參數sender,它指向了事件源對象,當使用RAISE EVENT語句觸發一個事件時,事件源的對象就會分配給這個sender引用,但是靜態事件沒有隱含參數sender
?
事件evt的定義也是在類或接口的定義部分進行定義的
非靜態事件只能在非靜態方法中觸發,而不能在靜態方法中觸發;而靜態事件即可在靜態也可在非靜態方法中進行觸發,或者反過來說:實例方法既可觸發靜態事件,也可觸發非靜態事件,但靜態方法就只能觸發靜態事件
2.8.2.???事件觸發
RAISE EVENT?evt [EXPORTING?p1 = a1 p2 = a2 ...].
該語句只能在定義evt事件的同一類或子類,或接口實現方法中進行調用
?
當實例事件觸發時,如果在event handler事件處理器聲明語句中指定了形式參數sender,則會自動接收事件源,但不能在RAISE EVENT …EXPORTING語句中明確指定,它會自動傳遞(如果是靜態事件,則不會傳遞sender參數)
CLASS?c1?DEFINITION.
PUBLIC?SECTION.
??????EVENTS?e1?EXPORTING?value(p1)?TYPE?string?value(p2)?TYPE?i?OPTIONAL.?"定義
METHODS?m1.
ENDCLASS.
CLASS?c1?IMPLEMENTATION.
METHOD?m1.
RAISE?EVENT?e1?EXPORTING?p1?=?'...'."觸發
ENDMETHOD.
ENDCLASS.
2.8.3.事件處理器Event Handler
靜態或非靜態事件處理方法都可以處理靜態或非靜態事件,與事件的靜態與否沒有直接的關系
INTERFACE?window.?"窗口事件接口
??EVENTS: minimize?EXPORTINGVALUE(status)?TYPE?i."最小化事件
ENDINTERFACE.?
CLASS?dialog_window?DEFINITION.?"窗口事件實現
?PUBLIC SECTION.?
??INTERFACES?window.?
ENDCLASS.?
INTERFACE?window_handler.?"窗口事件處理器接口
? METHODS: minimize_window??FOR EVENT?window~minimize?OF?dialog_window?
IMPORTING?status?sender.?"事件處理器方法參數要與事件接口定義中的一致
ENDINTERFACE.
2.8.4.???注冊事件處理器
實例事件處理器(方法)注冊(注:被注冊的方法只能是用來處理非靜態事件的方法):
SET HANDLER?handler1 handler2 ...?FOR?oref|{ALL INSTANCES}[ACTIVATION?act].
靜態事件處理器(方法)注冊(注:被注冊的方法只能是用來處理靜態事件的方法):
SET HANDLER?handler1 handler2 ...?[ACTIVATION?act].
oref:只將事件處理方法handler1 handler2注冊到?oref?這一個事件源對象
ALL INSTANCES:將事件處理方法注冊到所有的事件源實例中
ACTIVATION act:表示是注冊還是注銷
2.8.5.???示例
CLASS?c1?DEFINITION."事件源
PUBLIC?SECTION.
EVENTS:?e1?EXPORTING?value(p1)?TYPE?c,e2.
CLASS-EVENTS?ce1?EXPORTING?value(p2)?TYPE?i.
METHODS:trigger."事件觸發方法
ENDCLASS.
CLASS??c1?IMPLEMENTATION.
METHOD?trigger.
RAISE?EVENT:?e1?EXPORTING?p1?=?'A',e2,ce1?EXPORTING?p2?=?1.
ENDMETHOD.
ENDCLASS.
靜態(如下面的h1方法)或非靜(如下面的h2方法)態事件處理方法都可以處理靜態或非靜態事件,事件的處理方法是否只能處理靜態的還是非靜態事件與事件的靜態與否沒有關系,但事件的觸發方法與事件的靜態與否有關系(實例方法既可觸發靜態事件,也可觸發非靜態事件,但靜態方法就只能觸發靜態事件);但是,事件處理方法雖然能處理的事件與事件的靜態與否沒有關系,但如果處理的是靜態事件,那此處理方法就成為了靜態處理器,只能采用靜態注冊方式對此處理方法進行注冊。如果處理的是非靜態事件,那此處理方法就是非靜態處理器,只能采用非靜態注冊方式對此處理方法進行注冊
處理器的靜態與否與處理方法本身是否靜態沒有關系,只與處理的事件是否靜態有關
CLASS?c2?DEFINITION."監聽器:即事件處理器
PUBLIC?SECTION.
"靜態方法也可以處理非靜態事件,此方法屬于非靜態處理器,只能采用非靜態注冊方式
CLASS-METHODS?h1?FOR?EVENT?e1?OF?c1?IMPORTING?p1?sender.?
"非靜態方法處理非靜態事件,此方法屬于非靜態處理器,只能采用非靜態注冊方式
METHODS:?h2?FOR?EVENT?e2?OF?c1?IMPORTING?sender,??
"非靜態方法當然更可以處理靜態事件,此方法屬于靜態處理器,只能采用靜態注冊方式
?????????????h3?FOR?EVENT?ce1?OF?c1?IMPORTING?p2.?
ENDCLASS.
CLASS?c2?IMPLEMENTATION.
METHOD?h1?.
WRITE:?'c2=>h1'.
ENDMETHOD.
METHOD:?h2.
WRITE:?'c2->h2'.
ENDMETHOD.
METHOD:?h3.
WRITE:?'c2->h3'.
ENDMETHOD.
ENDCLASS.
DATA:?trigger?TYPE?REF?TO?c1,
??????trigger2?TYPE?REF?TO?c1,
handler?TYPE?REF?TO?c2.
START-OF-SELECTION.
CREATE?OBJECT?trigger.
CREATE?OBJECT?trigger2.
CREATE?OBJECT?handler.
? "由于h1、h2兩個處理方法分別是用來處理非靜態事件e1、e2的,所以只能采用實例注冊方式
SET?HANDLER:?c2=>h1?handler->h2?FOR?trigger,
"h3處理方法是用來處理靜態事件ce1的,屬于靜態處理器,所以只能采用靜態注冊方式
???????????????? handler->h3.?
??trigger->trigger(?).
? "雖然trigger( )方法會觸發?e1,e2,ce1?三種事件,但h1、h2未向實例trigger2注冊,而h3屬于靜態處理器,與實例無關,即好比向所有實例注冊過了一樣
??trigger2->trigger(?).
總結
- 上一篇: 销售单据条件价格明细表
- 下一篇: sap新总账中 CodingBlock客