[SAP ABAP開發技術總結]面向對象OO


由於歷史遺留原因,很多項目也還在使用老的ABAP過程化語句進行開發,但新的SAP很多的東西都已經通過類來實現了,比如BAPI(比類還早)、BADI、ALV,還有很多東西都了已經通過類來重寫了,所以為了與時俱進,還是使用類吧

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

2  TYPES, DATA, CLASS-DATA, CONSTANTS  for data types and data objects

2  METHODS, CLASS-METHODS, EVENTS, CLASS-EVENTS for methods and events

2  INTERFACES如果在類中,表示需要實現哪個接口;如果是在接口中,表示繼承哪個接口 for implementing interfaces

2  ALIASES  for 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不能與EXPORTINGCHANGING同時使用

image034

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 }...

2  dataobject表示是通用數據類型dataobject

2  complete_type為完全限定類型

2  OPTIONALDEFAULT兩個選項不能同時使用且對於EXPORTING類型的輸入參數不能使用

2  如果參數名p1前沒有使用VALUEREFERENCE默認為還是REFERENCE即引用傳遞

2  方法中的輸入輸出參數是否能修改請參考FormFunction參數的傳值傳址

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不能與EXPORTINGCHANGING同時使用

[EXCEPTIONS [exc1 = n1 exc2 = n2 ...]

[OTHERS = n_others] ] [)].

如果省略CALL METHOD,則一定要加上括號形式如果通過CALL METHOD來調用,則括號可加可不加

RECEIVING:用來接收METHODS /CLASS-METHODS RETURNING選項返回的值

如果EXPORTINGIMPORTINGCHANGINGRECEIVINGEXCEPTIONSOTHERS同時出現時,應該按此順序來編寫

使用此種方式調用(使用 EXPORTINGIMPORTING等這些選項)時,如果原方法聲明時帶了返回值RETURNING,只能使用RECEIVING來接受,而不能使用等號來接收返回值,下面用法是錯誤的:

num2 = o1->m1( EXPORTING p1 = num1 ).

2.6.4.   簡單調用

此方式下輸入的參數都只能是IMPORTING類型的參數,如果要傳CHANGINGEXPORTINGRAISINGEXCEPTIONS類型的參數時,只能使用上面通用調用方式

2  meth( )

此種方式僅適用於沒有輸入參數IMPORTING輸入\輸出參數CHANGING或者有但都是可選的、或者不是可選時但有默認值也可

2  meth( a )

此種方式僅適用於只有一個必選輸入參數IMPORTING)(如果還有其他輸入參數,則其他都為可選,或者不是可選時但有默認值也可),或者是有多個可選輸入參數IMPORTING)(此時沒有必選輸入參數情況下)的情況下但方法聲明時通過使用PREFERRED PARAMETER選項指定了其中某個可選參數為首選參數(首選參數即在使用meth( a )方式傳遞一個參數進行調用時,通過實參a傳遞給設置為首選的參數

2  meth( p1 = a1 p2 = a2 ... )

此種方式適用於有多個必選的輸入參數IMPORTING)方法的調用(其它如CHANGINGEXPORTING沒有,或者有但可選),如果輸入參數(IMPORTING)為可選,則也可以不必傳

2.6.5.   函數方法

Return唯一返回值

METHODS meth
    [IMPORTING
parameters
[PREFERRED PARAMETER p]]
    RETURNINGVALUE(r) typing
    [{RAISING|EXCEPTIONS} exc1 exc2 ...].

 

RETURNING 用來替換EXPORTINGCHANGING不能同時使用。定義了一個形式參數 r 來接收返回值並且只能是值傳遞

具有唯一返回值的函數方法可以直接用在以下語句中邏輯表達式IFELSEIFWHILECHECKWAITCASELOOP、算術表達式、賦值語句

函數方法可以采用上面簡單調用方式來調用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.  mesuper

等效於Java中的 thissuper

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) ...].

2  dataobject:表示是通用數據類型dataobject

2  complete_type:為完全限定類型

2  OPTIONALDEFAULT兩個選項不能同時使用

2  EXPORTING:定義了事件的輸出參數,並且事件定義時只能有輸出參數,且只能是傳值

 

非靜態事件聲明中除了明確使用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.
  "
由於h1h2兩個處理方法分別是用來處理非靜態事件e1e2的,所以只能采用實例注冊方式
 
SET HANDLER: c2=>h1 handler->h2 FOR trigger,
                
"h3
處理方法是用來處理靜態事件ce1的,屬於靜態處理器,所以只能采用靜態注冊方式
                 handler
->h3.
  trigger
->trigger
( ).
  "
雖然trigger( )方法會觸發 e1,e2,ce1 三種事件,但h1h2未向實例trigger2注冊,而h3屬於靜態處理器,與實例無關,即好比向所有實例注冊過了一樣
  trigger2
->trigger( ).

image035


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM