ABAP OO的八大理由

原貼地址:http://scnblogs.techweb.com.cn/abaplv/archives/127.htmlhtml

 

幾年前SAP BASIS 4.6爲ABAP擴展了OO功能,這是不少傳統的ABAP程序員陷入困境。首先對於ABAP程序員來講它們終於能夠經過OO這種開發方法得潛在價值來提升 開發效率和所開發程序的可維護性了。然而一直以來習慣於面向過程編程的ABAPER迅速的轉向OO模式也不是那麼容易,不少人仍是堅持使用傳統的面向過程 的開發模式,他們以爲不用OO也能夠獲得他們想要的。這篇文章的主要目的即是讓你明白OO能給你帶來什麼以及如何轉型爲OO模式。
不少關於ABAP OO方面的文章要麼過於抽象,要麼舉的例子過於簡單對於實際應用無關痛癢。本篇文章力圖經過簡單而又切合實際的例子經過面向過程和麪向對象兩種模式的比較來講明OO的優勢。
1.         首先ABAP OO具備更高層次的數據封裝性,從而加強了程序的可維護性和穩定性。在面向過程的模式裏,一個程序的全局變量區包含着許多不相干的變量,這些變量在一個區 域裏交織在一塊兒,這樣的話這個程序的某個功鞥對程序狀態的改變並不爲程序中另一個功能所知。爲保持整個程序的穩定性須要大量的約束和維護成本。而對於 OO模式,狀態是保存在對象上的。對象能夠把內部和外部數據和方法分隔開,以保證功能(OO中的方法)只能改變與它相關的數據,對象的屬性是不會被改變 的,從而保證了其在應用程序中的穩定性。
2.         ABAP OO能夠實現一個類的多個實例。(對象是由數據以及操做數據的方法組成的。),每個對象都有本身在類中定義的屬性值,而且能夠經過自己的方法來改變自己 的狀態。這就意味着開發者無需爲每一個對象創建數據和方法之間的聯繫也無需手工管理每一個對象的生命週期。在面向過程的方法中沒有多實例的概念,數據和功能是 相互分離的。你使用的是無狀態的功能,而且每次都須要經過傳遞參數來初始化它,而且手工將其佔有的內存清除。
3.         ABAP OBJECT經過繼承進一步加強了程序代碼的可重用性,這正是面向對象方法的一個重要方面。經過這個特色你能夠重複利用所繼承類的部分或者全部方法,只需 編寫類自己所特有的方法,這樣會減小爲每一個類編寫的方法,從而加強了程序的可維護性。而對於面向過程的編程來講,你將會受制於all-or- nothing的情況,你要麼調用全部的部分要麼就創建新的。
4.         ABAP OO是你能夠經過接口(interface)來調用對象的業務邏輯,而不是直接去使用對象,這樣就避免了你須要詳細瞭解每個對象的特定功能。這樣也避免 了你在須要修改某項功能的時候無需修改接口(interface)的內容,這也爲標準程序的修改提供了新的途徑,即BADI。面向過程的編程並無這種提 供對立的接口去聯繫某個對象的概念—接口只是經過form或function module的參數實現的。
5.         ABAP OO很是容易與事件驅動的模式結合在一塊。不一樣的應用之間是經過發佈與預約鬆散的耦合在一塊兒的,調用者和被調用者之間並非被動的綁定在一塊兒的。這種方式 與面向過程的方法相比更進一步的加強了靈活性,他們的綁定是緊密地,程序的執行流程也是預約義好的。
固然,這些好處都須要你從此再開發中是用 OO的方法來開發才能獲得。然而從新建模你應用程序的開發模式是使人沮喪和頭疼的,咱們保證這種狀況不會出現,讀 完這篇文章咱們相信你會獲得一樣的結論。固然,沒有說咱們須要從新建模已有的應用,咱們只是但願你在從此的開發過程當中最後考慮一下OO的模式。
若是你堅持認爲面向過程的模式對你來講已經足夠了,也請接着往下讀。經過使用對象的方法來代替form和function module你仍然能夠加強你的ABAP程序。java

 

1.         ABAP OO更加明確因此更易於使用。例如在使用ABAP OO你的程序的執行流程再也不是由運行時隱含的控制。這樣你就能夠本身去設計程序所執行的流程了而沒必要像面向過程那樣去了解和服從外部控制機制(即報表和 dialog screen的事件)。
2.         ABAP OO具備更加清晰的語法和語義規則,好比一些容易出錯的過期的語句在ABAP OO類中已經明確不能再使用。而在面向過程的程序中這些語法仍然被支持,頂多就是在關鍵的時候給你報個警告信息。
3.         ABAP的一些新技術只能經過ABAP OO來實現。例如全部新的GUI的概念好比SAP Control Framework和BSP只有經過ABAP OO的方式纔可以實現。而對於面向過程的ABAP你就只能使用傳統的screen和list processing了。
因此即使你在將來的開發中還不許備徹底的轉型爲OO,你可使用的OO技術來減小錯誤的隱患以及加強代碼的可維護性。下面的部分將會闡述如何達到這一目的。
那麼面向過程的ABAP和ABAP OO到底是孰優孰劣?下面的部分將逐一進行論述。首先先了解如下ABAP OO的年代史。
1.         SAP Basis Release 4.5發佈了ABAP OO的一個版本,引入了類接口的概念,並能夠經過類來建立對象(實例化類)。
2.         SAP Basis Release 4.6發佈了ABAP OO的徹底版本,引入了OO方式的重要概念繼承(inheritance),能夠經過多個接口來創建一個複合的接口。
3.         SAP WEB APPLICATION SERVER 6.10/6.20 SAP basis的下一代版本,在類之間引入了friendship的概念。並引入了對象服務(object service)能夠把對象存儲在數據庫中。
4.         SAP WEB APPLICATION SERVER 6.40引入了共享對象(Shared Objects)的概念,即容許在應用服務器的共享內存中存儲對象。這樣在這個服務器中的任何一個程序均可以訪問它。
幾個關鍵點
n         ABAP OO是ABAP編程語言的擴展
n         ABAP OO 是向下兼容的
n         SAP發佈ABAP OO是爲了進一步加強代碼的可重用性
n         隨着ABAP OO的發佈,ABAP運行時支持面向過程和麪向對象兩種模式c++

 

對於面向過程的模式,程序的運行一般是從 screen 的 dialog module 或 selection screen 的 start-of-selection 事件開始的。你在這些處理模塊中操做全局變量來實現需求的功能。你能夠經過內部的 form 和外部的 function module 來實現程序的模塊化。這些過程除了能夠操做全局變量外還能夠具有內部的本地變量來協助實現內部的一些特定功能。1程序員

對於OO編程,惟一的結構單位就是類,這裏類的實例對象取代了全局變量。這些對象封裝了應用的狀態和行爲。應用的狀態是用屬性來表明的它取代了面向過程當中的全局變量。應用的行爲是經過方法來實現的,他們用來改變應用的屬性或者調用其它對象的方法。2         ABAP OO支持OO和麪向過程的兩種模式,這樣在傳統的ABAP程序(好比報表,模塊池,功能池等)中你也可使用ABAP對象類。在這些程序裏你也就可使用基於面向對象的新技術了,好比一些用戶界面,避免了要想使用這些新技術必須從新編寫程序。web

n         目前大部分程序都是面向過程和ABAP OO 的混合體以下圖所示: 3左 邊是純粹的ABAP OO模式,全部的代碼都封裝在類中。你的應用中並不直接觸presentation layer(SAP Gui , Business Server Pages etc.),persistent data(database table,system file)。他們是經過類庫中的相應服務類來提供的。好比SAP Control Framework ,Desktop Office Integration, and Business Pages提供了與表現層的接口。對於SAP Web Application 6.10以上提供了與數據庫層接口的服務對象。
雖然純粹的OO模式技術上是可行的,可是現實中還存在着大量的兩種模式的混合體如右面的圖所示。ABAP 對象和麪向過程的技術同時應用,調用經常使用的功能模塊,調用屏幕或者直接訪問數據庫等在對象中都存在。混合的模式及利用了新技術又保護了已投入的成本。
兩種模式的選擇
正如本文所述,OO的模式是最佳的選擇,除非在絕對必要的狀況下才使用面向過程的模式。好比傳統的screen programming在OO中是不支持的,附錄中會進一步闡釋如何實現screen與OO的結合。
 
OO編程優於過程編程的五個緣由
下面的部分裏咱們將着重論述OO編程的主要優勢,儘管這裏所提到的優勢與其餘的OO語言(JAVA C++)沒有什麼太大的區別,咱們這裏着重在ABAP OO與傳統的ABAP程序相比而體現處來的優勢。咱們將經過實現一個銀行帳戶管理的簡單例子來比較兩種模式的差異。
緣由一:數據封裝
將 數據和程序封裝在一個組件中將使程序變得容易修改。不要把一個應用的全部的數據和功能放在同各超長的程序裏,你只須要把你的應用經過組件的穩定的接口把 須要的部分包進來便可。若是一個封裝的組件有一個好的接口,而這些接口的設計比較完善的話,那麼這些接口的內部結構就會被很好的隱蔽起來,對這個部件的內 部的修改便不會影響到應用的其餘部件。讓咱們來看看面向過程和麪向對象的方式是如何實現封裝的。
面向過程模式的封裝
在面向過程模式中有兩種變量:
全局變量:他在程序的所有分聲明,能夠在程序的仍何不分應用。
局部變量:他在某個過程(form of function module)中聲明也只能在其中應用。
全 局變量的生命週期取決於整個程序的生命週期,局部變量的生命週期取決於該過程的生命週期。因爲生命週期的限制,局部變量不適合於封裝,它是過程當中爲了達 到某個目的而使用的輔助變量。若是沒有使用TABLES和COMMON PARTS語句那麼程序中所聲明的全局變量只能被該程序內部的各個模塊調用。那麼這就決定了在面向過程的模式中數據的封裝只對程序本省有效。下面是一個簡 單的如何經過功能池實現對一個銀行賬號的封裝。
Function-pool Account
DATA: current_account TYPE accounts-amount.
 
Function deposit.
 * IMPORTING REFERENCE(amount) TYPE account-amount
Current_amount = current_amount + amount.
EndFunction.
 
Function withdraw.
* IMPORTING REFERENCE(amount) TYPE account-amount
* RAISING
               * CK_NEGATIVE_AMOUNT
 IF current_amount > amount.
    Current_amount = current_amount – amount.
 ELSE.
    RAISE EXCEPTION TYPE CK_NEGATIVE_AMOUNT.
 ENDIF.
ENDFUNCTION.
這 個模塊池封裝了銀行帳戶的餘額,而且經過功能模塊deposit和withdraw來處理銀行帳戶的餘額。雖然單單是一個銀行賬號的話這個模塊池工做的 很是好,但若是是多個應行賬號並要實現銀行賬號之間交互的功能,問題就出現了。爲了實現現實世界中多個銀行賬號的管理,你不得不爲每個銀行賬號建一個惟 一名字的模塊池和功能模塊,這顯然是不可取的。下面是個把全部銀行賬號封裝在一個模塊池中的例子:
FUNCTION-POOL accounts.
 DATA: account_table TYPE SORTED TABLE OF accounts
                    WITH UNIQUE KEY id.
ENDFUNCTION.
LOAD-OF-PROGRAM.
 SELECT * INTO TABLE account_table
           FROM accounts.
FUNCTION deposit.
* IMPORTING
*    REFERENCE(id) TYPE accounts-id
*    REFERENCE(amount) TYPE accounts-amount
DATA: account_wa TYPE accounts.
READ TABLE account_tabe
INTO account_wa
WITH TABLE KEY id = id.
Account_wa-amount = account_wa-amount + amount.
MODIFY account_table FROM account_wa.
ENDFUNCTION.
FUNCTION withdraw.
* IMPORTING
*    REFERENCE(id) TYPE accounts-id
*    REFERENCE(amount) TYPE accounts-amount
* RAISE
* CX_NEGATIVE_AMOUNT
DATA: account_wa TYPE accounts.
READ TABLE account_table
INTO account_wa
WITH TABLE KEY id = id.
IF account-amount > amount.
 Account-amount = account-amount – amount.
 MODIFY account_table FROM account_wa.
ELSE.
 RAISE EXCEPTION TYPE CX_NEGATIVE_AMOUNT.
ENDIF.
ENDFUNCTION.
FUNCTION transfer.
* IMPORTING
*    REFERENCE(id_from) TYPE accounts-id
*    REFERENCE(id_to) TYPE accounts-id
*    REFERENCE(amount) TYPE accounts-amount
* RAISE
* CX_NEGATIVE_AMOUNT
    CALL FUNCTION ‘withdraw’
       EXPORTING id = id
                   Amount = amount.
    CALL FUNCTION ‘deposit’
       EXPORTING id = id
                   Amount = amount.
ENDFUNCTION.
這 樣多個銀行賬號就被封裝在內表account_tab中,每一個銀行賬號是經過關鍵字ID來區分的。內表account_tab在模塊池被調用時被填充以 便模塊池中的全部功能模塊均可以使用它。功能模塊deposit和withdraw經過id來處理一個銀行賬號,而新的功能模塊transer來實現兩個 銀行賬號之間的轉帳。這樣咱們經過必定的技巧實現了多個銀行賬號的管理可是爲了區別每一個銀行賬號卻增長了每一個功能模塊接口參數的複雜性。
 
面向對象模式的數據封裝
OO模式的編程也有兩種數據類型,類實例的屬性和類方法中的本地變量。
實例屬性的生命週期依賴於對象的 生命週期,本地變量的生命週期依賴於類方法的生命週期。因此面向對象的本地變量與面向過程的本地變量的生命週期是同樣的。 它是類方法中的輔助變量與數據封裝無關。ABAP對象的數據封裝在類這個級別。能夠定義類屬性的可見性,它的級別分別是在類內可見,在子類中可見,或者在 外部類中可見。下面的例子演示瞭如何在類中封裝銀行帳號:
CLASS account DEFINITION.
 PUBLIC SECTION.
METHODS: constructor IMPORTING id TYPE account-id,
           Deposit IMPORTING amount TYPE accounts-amount,
           Withdraw IMPORTING amount TYPE accounts-amount
RAISING cx_negative_amount,,
           Transfer IMPORTING amount TYPE accounts-amount
                              Target REF TO account
                  RAISING cx_negative_amount.
PRIVATE SECTION.
 DATA amount TYPE accounts-amount.
ENDCLASS.
CLASS account IMPLEMENTATION.
 METHOD constructor.
     SELECT SINGLE amount INTO (amount)
                           FROM accounts
                          WHERE id = id.
 ENDMETHOD.
 METHOD deposit.
     Me->amount = me->amount + amount.
 ENDMETHOD.
 METHOD withdraw.
IF me->amount > amount.
 Me->amount = me->amount – amount.
ELSE.
 RAISE EXCEPTION TYPE cx_negative_amount.
ENDIF.
 ENDMETHOD.
 METHOD transfer.
     Me->withdraw( amount ).
     Target->deposit( amount ).
 ENDMETHOD.
ENDCLASS.
在 account類的定義部分能夠定義屬性和方法的可見性(private public)。類的定義把功能和數據結合到了一塊。理論上,前面例子的功能池也作到了這點,只不過在不一樣的數據模塊間進行交互的時候就暴露了其侷限性, 因此功能池只能說是多個功能模塊的容器還不能真正的共享數據。在ABAP OO的類中PUBLIC部分定義了其與外部交互的接口。在這個例子中描述類狀態的屬性是私有的,而對外的公共接口是操做這些屬性的方法。
這個例子 中的類既實現了前面面向過程的第一個例子的簡單功能也實現了第二個例子較爲複雜的功能。這個類的deposit,withdraw方法與第一個例 子的兩個功能模塊的做用相同,因爲你能夠建立一個類的多個對象,因此這個類只需封裝一個銀行賬號的數據便可,constructor方法用來爲不一樣的銀行 帳號初始化數據。因爲每一個對象都有它本身的數據,因此你不需爲類添加額外的參數。最後,不止於此,因爲一個對象能夠調用另一個對象的方法,那麼不一樣銀行 帳號之間的交互便有了更加簡潔的方案,這例子中transfer功能的實現要比前面第二個例子的實現簡單的多。
 
緣由二,實例化
對象的實例化是面向對象編程的一個重要特色。在ABAP OO中,經過實例化你能夠實現一個類的多個變體,這樣程序員即可以調用任何一個對象並讓他完成相應的功能(好比一個銀行賬號的收款存款和窗戶的打開關閉等)。
在 面向過程的編程中,當程序內容被編譯到內存中便隱含着一個實例化的過程,可是這個實例並不能爲程序員顯式的調用,由於這須要數據和功能的分離,而面向過 程的的程序員並非直接對對象進行操做,而是要告訴一個功能模塊須要修改那些數據(好比須要告訴功能模塊那個銀行賬號要付款或者那個窗戶要打開)。下面我 們將詳細描述這兩種不一樣的實例化之間的區別。
面向過程的實例化
大多數程序員可能沒有意識到其實在面向過程的程序裏也有相似於對象實例化的現象。程序自己在被調入內存的時候其實就是一個隱含的實例化過程,由於程序自己被調用或者程序中的某個過程被其餘程序調用了。
模塊池隱含實例化的例子
DATA: id1(8) TYPE n,
      Id2(8) TYPE n,
      Amnt TYPE p DECIMALS 2,
      Exc_ref TYPE REF TO cx_negative_amount,
      Text TYPE string.
TRY.
 Id1 = …..
 Id2 = …..
 Amnt = …..
 CALL FUNCTION ‘TRANSFER’
        Id_from = id1
        Id_to   = id2
        Amount = amnt.
 CATCH cx_negative_amount INTO exc_ref.
 Text = exc_ref->get_text().
 MESSAGE text TYPE i.
ENDTRY.
上面的例子演示了調用銀行帳戶模塊池的轉帳功能模塊的例子,兩個銀行帳戶是經過帳戶ID來區分的。
如 果銀行帳戶模塊池中的功能模塊是第一次被調用,那麼整個模塊池就會被調到調用程序的內部session中,模塊池的LOAD-OF-PROGRAM事件 就會被觸發。對應的事件部分充當着模塊池實例化的結構事件。若是在同一個內部session中,在同一個程序或另外一個程序中銀行賬號模塊池已經被調用,那 麼下一調用,模塊池已經被裝載到這個內部session中。因爲程序或者過程只有一次裝載到內存的過程,因此功能模塊即可以使用其所在模塊池中的全局數 據。
這種實例化對於數據封裝帶來了以下缺陷:
l         你沒法控制實例化的時刻(在一個較大的程序中功能模塊在任什麼時候候,任何地點都有可能被調用),這樣當一個程序在調用功能模塊的時候它將沒法知道是否另外一個程序或過程改變了模塊池的全局數據。
l         你沒法在內存中刪除模塊池的實例,由於模塊池的實例的生命週期取決於調用主程序的生命週期。若是你想在模塊池的全局數據中使用數據量較大的變量,那麼你在 使用後須要手工將其清除。另外模塊池通常是許多功能模塊的容器,這樣就會給內存帶來很大的壓力,即使是你只是在較短的時間調用很簡單的功能模塊。
l         每一個程序在內存中只能建立一個實例。正如咱們在緣由1種所看到的,這就限制了咱們充分發揮模塊池的數據封裝性。
還要注意的若是在模塊池中,全局變量不能被整取操做,那麼將是功能模塊對全局變量的使用變得更加危險。全局變量的狀態取決於功能模塊的調用順序,尤爲是在一個大程序裏,功能模塊在不一樣的地方都有可能調用,這樣就致使了模塊池全局變量狀態的不穩定。
 
面向對象的實例化
行如其名,在面向對象的模式中,對象是惟一存在的東西。對象是類的實例,是經過CREATE OBJECT語句來實現的。ABAP對象不可能被隱含的實例化,你經過指針變量來操做對象。
固然你經過指針所操做的對象不必定是本身建立的,這種現象主要是經過指針操做的對象頗有多是從其餘地方傳過來的,好比說工廠方法(factory method)或者接口參數。你能夠在一個類中建立多個對象每一個對象經過屬性都有本身的標識符和內容。
對象的生命週期是由使用者來控制的(其餘對象,程序或過程等),只要有指針變量指向他,他就在內存中存在。
如 果沒有指針變量指向對象,這個對象就會被自動的被ABAP內存收集器從內存中刪除。和程序的實例同樣,ABAP對象也存儲在主程序的內部SESSION 中。在640以後你就能夠在應用服務器的SHARED MEMORY中建立shared object了,這樣在這應用服務器上運行的任何程序均可以調用它。
下面的例子演示了從銀行帳號類中產生的兩個銀行帳號對象。
DATA: account1 TYPE REF TO account,
      Account2 TYPE REF TO account,
      Amnt TYPE p DECIMALS 2,
      Exc_ref TYPE REF TO cx_negative_amount,
      Text TYPE string.
CREATE OBJECT : account1 EXPORTING id = ….,
                 Account2 EXPORTING id = …..
TRY.
 Amnt = ….
 Account1àtransfer ( EXPORTING amount = amnt
                               Target = account2).
 CATCH cx_negative_amount INTO exc_ref.
 Text = exc_ref->get_text().
 MESSAGE text TYPE i.
ENDTRY.
指 針變量account1,account2是類account的對象的顯示的操做符。在CREATE OBJECT語句中每一個帳號標識被傳入到了對象的結構體。對象一旦被建立,帳號標識就不用再被聲明瞭。你能夠調用一個對象的transfer方法,經過通 過帳號指針變量來指明要轉入的帳號。
與面向過程的上面的例子相比,顯然面向對象的例子更加直接。在面向過程的例子裏你不得不爲每一個功能模塊指明 要操做的數據,而在面向對象的例子裏你只需調用 對象的方法那麼他就會自動地使用它本身的數據。值得注意的是例外信息咱們都是使用基於類的方法,這在610以後是被推薦的。在面向過程的程序中使用指針變 量exc_ref顯得有些另類,由於在非OO模式的程序中使用了OO模式的東西,這也是ABAP OO的一個天然特性。
 
緣由三:代碼重用性
代碼重用性是軟件維護和開發的一個重要衡量指標。咱們應當把一些通用的代碼放在一箇中心庫裏,而無須一遍一遍的重複編寫功能類似的代碼。下面就在代碼重用方面檢查一下ABAP OO和ABAP OP孰優孰劣。
面向過程的代碼重用性
在面向過程的模式中沒有什麼專門的機制來支持代碼的重用性。你能夠定義通用的過程,可是若是你想在特殊狀況下使用通用代碼,你不得不創建很龐大的模塊池,每一個功能模塊又不得不有複雜的參數,而每一個功能模塊中你又不得不使用複雜的分支語句,例如SWITCH CASE.。
好比爲了給銀行帳號加入兩個特殊的帳號,檢查帳號和存款帳號,咱們不得不修改咱們的程序以支持這種變化。下面的例子演示了對功能模塊withdraw的修改。
FUNCTION withdraw.
 CASE kind.
 WHEN ‘C’.
     PERFORM withdraw_from_checking_account USING id amount.
 WHEN ‘S’.
PERORM withdraw_from_savings_account USING id amount.  
 WHEN OTHERS.
    RAISE EXCEPTION TYPE cx_unknown_account_type.
  ENDCASE.
ENDFUNCTION.
FORM withdraw_from_checking_account.
      USING i_id TYPE accounts-id
             Amount TYPE accounts-amount.
 DATA: account_wa TYPE accounts.
 READ TABLE account_tab WITH TABLE KEY id = i_id
        INTO account_wa.
 Account_wa-amount = account_wa-amount – amount.
 MODIFY TABLE account_tab FROM account_wa.
 IF account_wa-amount < 0.
    ………..
 ENDIF.
ENDFORM.
FORM withdraw_from_savings_account.
      USING i_id TYPE accounts-id
             Amount TYPE accounts-amount
RAISING cx_negative_amount..
 DATA: account_wa TYPE accounts.
 READ TABLE account_tab WITH TABLE KEY id = i_id
        INTO account_wa.
 IF account_wa-amount > i_amount.
Account_wa-amount = account_wa-amount – amount.
MODIFY account_tab FROM account_wa.
 ELSE.
    RAISE cx_negative_amount.
 ENDIF.
ENDFORM.
這樣你就不得不怎加新的參數賬戶類型了
在這個例子中還得增長新的例外信息,即若是賬戶類型不在合理範圍以內的狀況。
最終爲了實現對不一樣的賬戶類型採起不一樣的處理邏輯,那麼你就不得不寫兩個form來分別處理兩種不一樣的狀況。經過CASE語句來實現分支。
ABAP OO的代碼可重用性
在ABAP OO中經過繼承來實現代碼的可重用性,能夠經過通用的父類來派生特殊的子類。這樣好處是簡單的類既可代替代碼龐雜的模塊池,簡單的方法參數既可代替功能模 塊複雜的參數,最重要的是經過繼承實現了類的多態。這樣就實現了子類的對象仍然可使用父類的方法。這大大加強了軟件開發的建模能力。
 
下面的例子是一個修改版的賬戶,他已經做爲兩個子類checking account和saving account的父類。
CLASS account DEFINITION.
 PUBLIC SETION.
 PROTECTED SETION.
    DATA amount TYPE accounts-amount.
ENDCLASS.
CLASS account IMPLEMENTATION.
 METHOD withdraw.
    ME->amount = ME->amount – amount.
 ENDMETHOD.
ENDCLASS.
正如你所見屬性amount已經由private改成protected以便它的兩個子類也能夠放問它。方法withdraw已經被通用化,它再也不拋出異常。這些改變外界不會察覺到,這也是實現多態的前提條件。父類account的子類checking account
CLASS checking_account DEFINITION
INHERIATING FROM account.
 PUBLIC SECTION.
    METHODS withdraw REDEFINITION.
ENDCLASS.
CLASS checking_account IMPLEMENTATION.
 METHOD withdraw.
Super->withdraw ( amount ).
IF me->amount < 0.
 …..check debit amount
ENDIF.
 ENDMETHOD.
ENDCLASS.
父類的子類savings_account
CLASS savings_account DEFINITION
INHERIATING FROM account.
   PUBLIC SECTION.
     METHOD withdraw REDEFINITION.
ENDCLASS.
CLASS savings_account IMPLEMENTATION.
 METHOD withdraw.
IF me->amount > amount.
 Me->amount = me->amount – amount.
ELSE.
 RAISE EXCEPTION TYPE cx_negative_amount.
ENDIF.
 ENDMETHOD.
ENDCLASS.
通 過INHERIATING FROM使得父類和子類有着相同的屬性和參數。經過方法withdraw REDEFINITION來從新編寫子類的同名方法。經過super->能夠調用父類的方法,在兩子類中這兩個withdraw方法根據不一樣的賬戶 類型做了改動,例如在這兩個子類中分別對當賬戶餘額爲負數是拋出異常或者貸向處理。
下面的例子演示了一個父類,兩個子類的使用:
DATA: account1 TYPE REF TO account,
       Account2 TYPE REF TO account,
       Amnt TYPE p DECIMALS 2,
       Exec_ref TYPE REF TO cx_negative_amount,
       Text TYPE string.
CREATE OBJCET account1 TYPE checking_account
                  EXPORTING id = ..
CREATE OBJCET account2 TYPE savings_account
                  EXPORTING id = …
TRY.
   Amnt = …
   Account1->transfer( EXPORTING amount = amnt
                                      Target = account2 ).
 CATCH cx_negative_amount INTO exec_ref.
 Text = exec_ref->get_text().
 MESSAGE text TYPE i.
ENDTRY.
與 前面的面向對象的例子相比,惟一的不一樣即是在建立對象是,類別分別改成checking_account和savings_account。不過 account1和account2在變量聲明部分仍然使用的是類account。對於上面的例子除了對象指針變量,對於使用它的程序,它與前面的例子, 程序感受不到他有什麼區別,然而不一樣類型的對象會自動調用屬於本身的方法。這樣的好處是顯而易見的,在面向過程的功能模塊中爲了實現不一樣類型賬戶之間的轉 帳你爲此不得不付出成級數倍的增加,而在面向對象的模式中咱們無需改變transfer方法。
 

緣由4:INTERFACE
INTERFACE通俗的講就是經過一個程序來調用另一個程序的數據和功能。在模塊化和相互訪問的世界 中,INTERFACE提供了兩個部件之間聯繫的 橋樑。在ABAP OO中提供了類與調用者之間獨立的INTERFACE,這樣就把類和使用者之間分離開來。而在ABAP OP
(oriented procedure)中沒有獨立的INTERFACE,而是提供了程序之間隱式的INTERFACE和程序和過程之間顯式的INTERFACE。咱們來進一步研究一下這兩種模式的INTERFACE。
面向過程的INTERFACE
面向過程的INTERFACE有必定的侷限性。
l         用TABLES或COMMON PART聲明的全局變量即是程序之間隱式的INTERFACE,在經典的ABAP語言中一旦用TABLES定義了全局變量,就隱含的定義了屏幕與程序之間的接口。邏輯數據庫也使用了這種隱式的接口方式。
l         一個程序的過程能夠被另一個程序調用,是程序之間的功能INTERFACE。程序中的功能模塊和form都是公開的。從外邊調用的其餘程序的form或功能模塊的程序能夠訪問他們所在的主程序的變量。
當 用SUBMIT調用程序的時候,除了能夠用selection screen上的parameters或select options做爲顯式的INTERFACE外,程序之間在沒有其餘顯式的INTERFACE了。若是開發人員修改了一個程序的隱式INTERFACE, 可能會致使調用這個程序的其餘程序失效而開發者確感受不到這一點。讓外部程序無限制的去訪問主程序中的數據是有分險的。
OO的INTERFACE
在 OO模式中能夠定義INTERFACE的三個訪問級別:PUBLIC,PRIVATE,PROTECTED。PUBIC表示功能或數據是對外開放的。 PRIVATE指明INTERFACE只能在類內部使用而PROTECTED則說明之有其自己或者其子類能夠訪問。而對於友好類則能夠訪問 PROTECTED和PRIVATE部分。對於子類,其繼承了父類的INTERFACE,並能夠對其進行擴展。
爲了提升穩定性和可重用性,能夠把 類的PUBLIC部分單獨分離出來作爲類對外INTERFACE的獨立描述。這種INTERFACE沒有任何具體的代 碼,它只有類的所有或部分全局屬性。獨立的INTERFACE能夠被多個類使用,它表明了類的某個具體方面,好比統一持久屬性等。由於他們與具體的功能無 關,因此一個對象的不一樣特性能夠創建不一樣的INTERFACE,他們之間的關係以下圖所示:數據庫

11
 
INTERFACE經過語句INTERFACE….ENDINTERFACE來定義。它能夠有與類同樣的部件。任何類均可以有一個或多個 INTERFACE。經過在類的public部分進行聲明,這樣在interface中定義的public部分就成爲類public interface的一部分。包含獨立interface的類必須爲類提供服務,這樣用戶能夠經過interface來訪問類,而無需知道其中的訪問細 節。
那麼,實現這種機制的原理是什麼呢?基本原理是你能夠聲明指針變量,而這個指針變量能夠指向實施這個interface的任何類的對象。調用 者只是與 interface指針變量工做,而其無需知道其實際指向的是哪一個類的對象。而調用者只需知道這個interface的相關屬性就能夠了。由於實現 interface的類,就會實如今interface中定義的部分,因此只要經過interface調用者就能夠實現本身的目的了。每一個 interface按照本身的目的定義本身的interface方法。好比不一樣類型的銀行賬號,利息計算的方法不一樣。在interface中方法名和其參 數是相同的。因此interface和繼承是OO中實現多態的兩種方式。經過interface指針變量來訪問對象與經過父類的指針變量來訪問子類的對象 的道理同樣。
下面的例子演示了兩個毫無關係的類,account和customer:
CLASS account DEFINITION.
 PUBLIC SECTION.
INTERFACES if_serializable_object.
….
ENDCLASS.
CLASS customer DEFINITION.
 INTERFACES if_serializable_object.
ENDCLASS.
DATA:account TYPE REF TO account,
      Customer TYPE REF TO customer,
      Serializable_objects TYPE TABLE OF REF TO if_seriazable_object,
      Serializable_object TYPE REF TO if_serializable_object,
      Xmlstr TYPE string.
CREATE OBJECT accout EXPORTING id = ……,
                Customer.
APPEND: account TO serializable_objects,
         Customer TO serializable_objects.
LOOP AT serializable_objects INTO serializable_object.
 CALL TRASFORMATION id
        SOURCE obj = serializable_object
        RESULT xml = xmlstr.
ENDLOOP.
Account 是咱們所熟悉的類,customer多是整個業務應用的一部分或其餘的什麼,這都無所謂。可是這些類都有統一的interface,這是 在6.10以後所支持的。本例中的interface可使你把對象的屬性序列化到xml文檔中。具備INTERFACE if_serializable_object的類都具有了序列化的屬性並對外提供了這種屬性。
上面的例子演示瞭如何使用類account和 customer的接口,在這個例子中,內表serializable_objects做爲 if_serializable_object指針變量的集會。假如說在程序中的某個部分,內表被遍歷,那麼經過語句CALL TRANSFORMATION能夠將其序列化。在遍歷的循環中對象的類是無關的,只有序列化的對象的屬性是相關的。獨立的interface使你只關注對 象的某個方面,而不關注其餘方面。相比之下,對於功能模塊,你要輸入的參數,與你手頭的想要作的事情無關。
緣由五,事件
應用中,用戶界 面的鼠標單擊,新賬戶的創建,均可以觸發一個事件,這個事件要被他感興趣的處理者知道。事件和事件處理與調用過程有類似之處:觸發事件就相 當於調用自程序,處理事件就至關於被調用子程序的主程序。區別是被調用的子程序和調用程序是幫定的一起的,而事件則不一樣,處理者有可能處理觸發的事件, 但也不必定。面向過程的ABAP的事件處理是經過運行時來實現的。而在OO中,類和對象既能夠觸發事件,又能夠處理事件。下面將詳細討論這兩種模式對事件 處理的支持。
 
緣由五,事件
應用中,用戶界面的鼠標單擊,新賬戶的創建,均可以觸發一個事件,這個事件要被他感興趣的處理者知道。事件和事件處理與調 用過程有類似之處:觸發事件就相 當於調用自程序,處理事件就至關於被調用子程序的主程序。區別是被調用的子程序和調用程序是幫定的一起的,而事件則不一樣,處理者有可能處理觸發的事件, 但也不必定。面向過程的ABAP的事件處理是經過運行時來實現的。而在OO中,類和對象既能夠觸發事件,又能夠處理事件。下面將詳細討論這兩種模式對事件 處理的支持。
面向過程的事件處理
對於面向過程的ABAPER來講事件的概念能夠說是再熟悉不過了。沒有事件你就沒法執行ABAP程序。 要想經過SUBMIT來執行一個程序,那麼它必須有 個start-of-selection的事件,它是由運行時觸發的。對於屏幕處理邏輯,必須可以處理PBO和PAI事件。另外在SELECTION SCREEN中你還能夠處理AT SELECTION-SCREEN事件,在LIST中處理AT-LINE-SELECTION事件和AT USER-COMMAND事件。
面向過程事件的一個問題即是他的隱含性。除了兩個例外外,你沒法在程序裏觸發事件,這兩個例外是在邏輯數據庫的程 序裏能夠經過PUT觸發GET事件。經過 SET USER-COMMAND觸發AT USER-COMMAND事件。其次即是爲了寫好ABAP程序,你必須瞭解特殊的處理流程,好比報表程序流程,對話業務流程,selection screen流程,list流程等。最後,你沒法編寫和處理本身的事件。這就意味着調用者和被調用模塊間是一種緊密聯繫,一旦你在某個地方調用了某個模 塊,要麼這個模塊存在要麼就會出現運行時錯誤。
OO模式下的事件處理
在ABAP OO中,事件是做爲類中的一部分被顯式聲明的。若是一個事件在類中已經被聲明,那麼在這個類的方法中能夠經過RAISE EVENT來觸發它。經過RAISE EVENT除了告訴系統即將觸發一個事件外還能夠經過它來傳遞參數給它的處理者。這個處理者即是其餘類或者該類中的一個方法。這個方法靜態的定義爲某個具 體事件的處理者。在程序的運行過程中事件處理者能夠隨時被動態的激活或使其失效,而且一個事件能夠同時擁有多個事件處理者。
ABAP OO中事件處理的好處即是調用者和被調用者之間的分離。不是調用方法,而是經過觸發事件來調用這個事件全部的處理者(即靜態的定義好事件的處理者而後在運 行時動態的激活它)。這與傳統的面向過程模式正好相反,調用者必須明確的知道它要調用什麼。發佈和調用的兩個狀態,即事件處理者的靜態定義和事件處理的動 態激活爲事件編程帶來了很大的靈活性。下面的例子演示瞭如何是咱們的銀行賬號可以處理事件。
CLASS checking_account DEFINITION INHERIATING FROM account.
 PUBLIC SECTION.
METHODS deposit REDEFINITION.
….
EVENTS adivising_required
        EXPORTING value(amount) TYPE accounts-amount.
PRIVATE SECTION.
DATA: limit TYPE accounts-amount VALUE ‘5000.00’.
ENDCLASS.
CLASS checking_account IMPLEMENTATION.
 METHOD deposit.
     Super->deposit( amount ).
     IF me->amount > limit.
       RAISE EVENT advising_required
              EXPORTING amount = me->amount.
     ENDIF.
 ENDMETHOD.
ENDCLASS.
 
CLASS advisor DEFINITION.
 PUBLIC SECTION.
METHODS constructor.
….
PRIVATE SECTION.
….
METHODS receive_notification.
          FOR EVENT advising_required OF checking_account.
ENDCLASS.
CLASS advisor IMPLEMENTATION.
 METHOD constructor.
     …
     IF …
        SET HANDLER me-receive_notification FOR ALL INSTANCES.
     ENDIF.
 ENDMETHOD.
 …..
 METHOD receive_notification.
     「do something
 ENDMETHOD.
ENDCLASS.
這 裏子類checking_account增長了事件advising_required.這個事件在重寫的deposit的方法中當amount超過 limit的時候觸發。在另外一個類advisor中爲事件advising_required定義了處理者receive_notification。在 結構方法中,經過if塊決定了那些銀行賬號能夠觸發事件。在咱們的例子了advisor對象將會響應任何一個銀行帳號的事件,固然你也能夠在SET HANDLER語句中經過single object來替換ALL INSTANCES來限制觸發事件的銀行帳號。這樣你就能夠作到經過特定的銀行賬號來觸發advisor的receive_notification方 法。
 
是否已經決定轉向ABAP OO了
從SAP 4.6C開始,ABAP已經成爲既能夠面向過程又能夠面向對象的混合式語言了。使用了ABAP OO的新特徵將使你的ABAP開發大受裨益。
這些新特徵包括:
u       類是對象的模版
u       對象是經過指針變量來引用的
u       繼承
u       獨立的interface
u       對象能夠觸發和處理事件
前面已經詳細描述了這五個特色,固然,這是全部面嚮對象語言都具備的特性,不過ABAP是專門面向商務應用的語言。它比java和c++更加簡單,去掉了那些複雜而且容易出錯的概念。它引入了觸發事件和處理事件的機制,這種機制在其餘語言中只有interface才具備。
如 果仍是沒有決定是否徹底的跨向ABAP OO,ABAP語言的混合性使你仍然能夠把ABAP OO和麪向過程的模式混合使用。這種方式既保護了已有的面向過程的ABAP產品又可讓你充分利用ABAP OO的新特性。下面將進一步從三個方面闡述如何用ABAP OO來提高你的ABAP程序。
經過ABAP OO提高ABAP程序的另外三個理由
前面主要針對OO編程的特色和方法闡述了ABAP OO的好處。不過對於ABAP自己它還有額外的好處。下面將着重介紹如何經過這些方面來以較少的成原本提高ABAP程序,儘管你還不想徹底轉入ABAP OO。
緣由1,ABAP OO更明確更容易被使用。
使用ABAP對象更加明確容易被使用。透過表面你將會發現他有更大的益處。看下面一個簡單的報表的例子。
REPORT simple_report.
NODES spfli.
GET spfli.
 WRITE: / spfli-carrid, spfli-connid …
認 爲它簡單的緣由是你並不知道後臺發生了什麼。代碼看起來簡單,可是後臺的運行卻並不簡單。經過查看文檔你就會發現運行這個與邏輯數據聯繫在一起的報表 的流程至少包括十個步驟,其中至少有一個循環和兩個屏幕的處理。早期的ABAP,這種方式是想給應用開發人員提供一個自動的報表處理機制。若是你能看到效 果的話,自動化從直覺上來看是很好的,不然你就會以爲無所適從。因此,若是你在一個熟悉的領域進行開發一切都OK,一旦進入到一個不熟悉的環境,一切都變 得那麼高深莫測。好比:
l         咱們對全局變量接口的認識,它是屏幕和應用程序的接口,也是程序和邏輯數據庫之間的接口。
l         面向過程的ABAP程序不少方面都是有運行時自動控制的,他們是被屏幕或程序流所驅動的。
相比之下ABAP對象就會變得比較簡單,它不容易出錯,而且是由許多簡單和獨立的概念組合而成的。
l         類具備屬性和方法
l         對象是類的實例
l         對象是經過指針變量來訪問的
l         對象有獨立的interface
 
學會ABAP OO一些簡單的語句以後,你就能夠經過開發程序直接告訴系統它須要作什麼。須要系統作什麼是由你明確告訴你的,系統不會作任何隱含的動做。你不須要爲了瞭解系統一些隱含的動做而去讀大量的文檔,你只需去看程序自己就能夠了。
下面的代碼演示瞭如何把一個面向過程的邏輯數據庫程序轉換爲面向對象的邏輯數據庫程序,他會變得更加清晰。
CLASS ldb DEFINITION.
 PUBLIC SECTION.
METHODS read_spfli.
EVENTS spfli_ready EXPORTING value(values) TYPE spfli.
 PRIVATE SECTION.
    DATA spfli_wa TYPE spfli.
ENDCLASS.
CLASS ldb IMPLEMENTATION.
 METHOD read_spfli.
     SELECT * FROM spfli INTO spfli_wa.
        RAISE EVENT spfli_ready EXPORTING values = spfli_wa.
     ENDSELECT.
 ENDMETHOD.
ENDMETHOD.
ENDCLASS.
 
CLASS report DEFINITION.
   PUBLIC SECTION.
      METHODS start.
   PRIVATE SECTION.
      DATA spfli_tab TYPE TABLE OF spfli.
      METHODS: get_spfli FOR EVENT spfli_ready OF ldb
                 IMPORTING values,
                 Display_spfli.
ENDCLASS.
CLASS report IMPLEMENTATION.
 METHOD start.
     DATA: ldb TYPE REF TO ldb.
     CREATE OBJECT ldb.
     SET HANDLER me->ge_spfli FOR ldb.
     Ldb->read_spfli().
     Display_spfli().
 ENDMETHOD.
 METHOD get_spfli.
     APPEND value TO spfli_tab.
 ENDMETHOD.
 METHOD display_spfli.
     ……
 ENDMETHOD.
ENDCLASS.
這 裏值得注意的是與面向過程的邏輯數據庫相比面向對象的有了更加明確的接口。經過PUBLIC部分你能夠知道這個類都提供了那些外部服務。爲了運行這個報 表,你能夠把這個類與OO事務代碼結合起來使用。不像經過GET隱含的處理事件,report類裏有明確的處理事件方法get_spfli。而且數據顯示 部分也從數據處理部分分離出來了。
比較先後這兩個例子,你會發現後者只需經過程序自己就能夠理解整個程序的功能了。這裏不存在任何黑匣子。同時 經過這個例子咱們也剔出了一種誤解,即程序開 發的簡化並不意味着確定就是更少的代碼,有時並非這樣。固然,若是你想讓一個不懂ABAP REPORT的人弄明白麪向過程的ABAP程序,你不得不寫大量的註釋。
從這個例子咱們能夠明顯地看出ABAP oo使得程序變得更加容易理解,易於維護更加可靠。
 

緣由2:ABAP OO在類中有更嚴格的語法檢查
面向過程的ABAP經歷了較長時間的成長,這也帶來了以下結果:
l         存在着大量的過期的語句
l         存在着不少交叉的概念
l         有一些奇怪的系統行爲
l         有些技術顯得較難理解
因爲不能影響已有的代碼,ABAP OO的版本引入了更加嚴格的語法檢查以剔出面向過程的ABAP程序一些弊病,主要包括:
l         禁止使用過期的ABAP語句
l         使一些隱含性的語法變得更加明確
l         查明並禁止不正確的數據處理
注意:
向 下兼容的一些ABAP語法在ABAP OO以外仍然被支持,這樣你就不必爲了使用的新版本的ABAP而去修改原來的程序。從另外一個角度來說,因爲有大量的現存程序存在,不得不保留用新的概念 來剔出一些過期的概念對語言自己來說也是一個沉重的負擔。若是你在ABAP對象以外使用下面列表中之外的功能,語法檢查最多也只能給你個警告的信息。若是 想去掉這些警告信息,最好使用下面列表中的替代方式。
Context Description
Syntax notation No special characters in names; no negative length specifications, no multi-line literals
Declarations LIKE references to data objects only; no implicit length of specifications for data types I, f, d or t; no operational statements in structure definitions;FIELDS,RANGES,INFOTYPES,TABES,NODES,COMMON PART,OCCURS,NO-LOCAL not permitted
Operations CLEAR…WITH NULL,PACK,MOVE…PERCENTAGE;ADD-CORRESPONDING;DIVIDE-CORRESPONDING;SUBSTRACT-CORRESPONDING,MULTIPLY-CORRESPONDING;ADD THEN…UNTIL…,ADD FROM…TO…;CONVERT(DATE INVERTED DATE) not permitted
String Processing Not permitted on numeric processing
Field Symbols No implicit types; FIELD-SYMBOLS…STRUCTURE;ASSIGN…TYPE;ASSIGN LOCAL COPY OF,ASSIGN TABLE FIELD not permitted.
Logic expressions Operators ><,=<;= not permitted; table used with IN must be a selection table
Control structures No operational statements between CASE and WHEN;ON-ENDON not permitted
Internal Tables No header lines; no implicit work areas; no redundant key specifications; compatible work areas required where necessary; obsolete READ variants, COLLECT,SORTED BY,WRITE TO itab , PROVIDE not permitted
Procedures(methods) No implicit type assignment; compatible initial values only; passing of sy-subrc and raising of undefined exceptions not permitted
Program calls No joint of USING and SKIP FIRST SCREEN when calling transactions;passing formal parameters implicitly in CALL DIALOG not permitted
Database accesses No implicit work areas in Open SQL;READ,LOOP,REFRESH FROM on database tables not permitted; VERSION addition to DELETE and MODIFY not permitted; no PERFORMING addition in Native SQL
Data clusters No implicit identifiers; no implicit parameter names; no implicit work areas; MAJOR-ID and MINOR-ID not permitted
Lists DETAIL,SUMMARY,INPUT,MAXIMUM,MINIMUM,SUMMING,MARK,NEW-SECTION, and obsolete parameters are not permittedexpress

上面的表格列舉了在類中一些語法的限制,使用上面列表中的任何一個限制的語法都會鬥志語法檢查的錯誤。能夠在ABAP文檔中找到這些限制的替代方式。
下面經過舉例說明使用更加清晰的ABAP OO語法的好處:
在傳統的面向過程的語法中定義內表的語句以下:
DATA BEGIN OF itab OCCURS 0.

CLEAR itab.
而在ABAP OO中就只能採用下面這種方式定義內表了:
DATA itab TYPE TABLE OF …

CLEAR itab.
過 去的內表的定義方式很是容易引發混淆。這種方式除了定義了內表變量,它也同時定義了一個work area。一個名字表明兩個變量顯然很是容易引發混淆。在ABAP OO中對此進行了嚴格的約束,內表的定義沒有隱含的定義表頭,那麼CLEAR語句就是明確的清除內表的內容了。並且在傳統的ABAP程序中,你不得不去判 斷你所操做的是內表仍是表頭,這樣便很容易致使程序出錯。而在ABAP OO中禁止了這種表頭,那麼就避免容易產生此種錯誤的弊病,它要求必須聲明一個獨立的表頭變量來處理內表中的內容從而使程序變得更加清晰而易於維護。編程

 

下面的例子比較了兩種模式下從數據庫中取數的不一樣之處:
在面向過程的ABAP程序中:
TABLES:dbtab.
SELECT * FROM dbtab.
在面向對象的ABAP程序中
DATA wa TYPE dbtab.
SELECT * INTO wa FROM dbtab.
TABLES隱含的聲明瞭一個與數據庫表名相同的結構變量,那麼對數據庫表內容的操做都使用這個隱含的變量。而在ABAP OO中,這種隱含的方式是不被容許的。TABLES語句是禁用的,必須使用更加明確的語句。
下面是另外一個例子:
在面向過程的ABAP程序中:
FIELD-SYMBOLS <fs>.
IF <fs> IS ASSIGNED.
 
ENDIF.
在面向對象的ABAP程序中:
FIELD-SYMBOLS <fs> TYPE ANY.
IF <fs> IS ASSIGNED.
 
ENDIF.
在ABAP OO中形參和FIELD SYMBOL必須明確的指定類型,而在過程的ABAP程序中是沒有必要的。若是沒有明確指定FIELD SYMBOL的類型,ABAP運行時就會自動把SPACE分配給這個field symbol。這樣的話在過程的ABAP程序中判斷語句的返回結果爲TRUE,而在ABAP OO中則爲false。
最後一個例子以下:
在過程的ABAP程序中;
DATA number TYPE I VALUE ….
TRANSLATE number TO UPPER CASE.
在ABAP OO中
DATA number TYPE I VALUE …
TRANSLATE number TO UPPER CASE.
在過程的ABAP程序中對數字型的字符型操做abap運行時會給警告信息,而在ABAP OO中則會給錯誤信息。在ABAP OO中,系統運行時保證了對應的操做必須針對對應的變量。
緣由3:ABAP OO支持一些新的技術
SAP許多新的技術都是基於ABAP OO的,那麼在你的項目中必須對面對這一點。許多基礎的技術都在ABAP OO中發佈了,這些包括:
l         User dialog的架構,如SAP control framework(CFW),Business Server Pages(BSP)以及Desktop Office Integration(DOI)等。
l         Frameworks for persisting data in the database(Object Service) and Shared Objects(area classes)
l         Service classes CL_GUI_FRONTEND_SERVICES for working with data at the presentation server
l         Laguate related classes,such as Run Time Type Services(RTTS) classes on CL_ABAP_EXPIMP subclasses for extended EXPORT/IMPORT functionality for example.服務器

 

緣由3:ABAP OO支持一些新的技術
SAP許多新的技術都是基於ABAP OO的,那麼在你的項目中必須對面對這一點。許多基礎的技術都在ABAP OO中發佈了,這些包括:
l         User dialog的架構,如SAP control framework(CFW),Business Server Pages(BSP)以及Desktop Office Integration(DOI)等。
l         Frameworks for persisting data in the database(Object Service) and Shared Objects(area classes)
l         Service classes CL_GUI_FRONTEND_SERVICES for working with data at the presentation server
l         Laguage related classes,such as Run Time Type Services(RTTS) classes on CL_ABAP_EXPIMP subclasses for extended EXPORT/IMPORT functionality for example.
SAP的趨勢是一些新的基礎服務都將用面相對象的模式開發,這就意味着若是想應用一些新的技術那你就不得不接觸ABAP OO。若是在一些新的項目中不得不使用ABAP OO的架構強烈建議使用OO的方式進行開發。儘管面向對象和麪向過程的混合模式在ABAP程序中是容許存在的,可是不建議這種狀況的出現,由於這樣反而使 成變得更加不易於維護。應儘可能避免使用面向過程的一些概念來開發程序,除了下面一些特殊的狀況:
l         把屏幕封裝在模塊池中,一些須要遠程調用的功能模塊。
l         內部模塊化應儘可能避免使用subroutine,他們的參數沒有方法先進。Subroutine的參數與位置有關而方法是與參數名結合到一塊的。另外 subroutine支持指針變量。另外subroutine參數的類型的檢查只在運行時有效,而method在編譯時就檢查。建議使用類方法 CLASS-METHODS而不是subroutine。
結論
使用的面向對象的方法即是使用現代的軟件的開發技術,它解決了一些複雜開發項目的問題。經過本文咱們瞭解到了面向對象的方法有以下好處:
l         Better encapsulation
l         Support for multiple instantiation
l         Better technique for reusing code
l         Better interfaces
l         An explicit event concept
即使你還不想徹底轉入ABAP OO,也見你多利用ABAP OO的特性來加強程序的質量
l         儘可能使用method
l         使用static method來代替subroutine
l         只有在必要的時候才使用function module
l         儘可能把面向過程和麪向對象的源碼分離開來
l         把屏幕邏輯的開發和應用邏輯的開發分離開來
l         不須要去掉‘UNICODE CHECK ACTIVE’
經過這篇文章的論述,對你程序開發的方式提供了新的思路。咱們但願可以說服你轉向ABAP OO。固然這種轉換並非讓你接觸更加複雜的語言,而是爲你提供了更好的機會和靈活性來知足你的要求:
l         從最低層次的應用來說,若是你在開發報表,你可能不須要來實例化類,而使用類的static method來實現報表邏輯,你仍然能夠看到你的程序被改進了
l         從較高層次的應用來說,你可能在一個項目中應用OO的模式。這樣的項目涉及到OO開發的不少細節階段,這也超出了本文的範圍。
對於大多開發者來講,狀況老是介於二者之間。想其餘面向對象的語言同樣,面向對象的開發並意味着你都要在UML方面付出太多的精力。沒必要擔憂ABAP OO的應用會給你帶來更多的麻煩。一旦你真正使用了它,你就會以爲我爲何不早用它呢!session

 

將經典的屏幕邏輯從OO的應用程序中分離出來正如你所看到的,在大部分程序中屏幕邏輯和應用邏輯是緊密地聯繫在一塊兒的。這些程序都是用戶通 過在屏幕中輸入數據來驅動的,應用邏輯都寫在modue或 event block中。而對於ABAP OO來講,它主要是用來寫應用邏輯而非屏幕邏輯。面向對象的ABAP OO不支持屏幕編程。若是你想用OO的模式編寫ABAP程序,你可能面臨的問題即是如何把屏幕程序與之結合起來。答案即是把應用邏輯從程序界面中分離出來。下面的一個簡單的例子講給你演示如何作到這一點。下面的代碼演示瞭如何經過模塊池把應用程序須要的屏幕封裝在一塊兒。FUNCTION-POOL flight_screens.SELECTION-SCREEN BEGIN OF SCREEN 100 AS WINDOW.PARAMETERS: p_carrid TYPE sflight-carrid,              P_connid TYPE sflight-connid,              P_fldate TYPE sflight-fldate.SELECTION-SCREEN END OF SCREEN 100.TABLES sflight.FUNCTION get_flight_parameters. CALL SELECTION-SCREEN 100 STARTING AT 10 10. Carrid = p_carrid. Connid = p_connid. Fldate = p_fldate.ENDFUNCTION.FUNCTION get_plane_type. Sflight-planetype = plane_type. CALL SCREEN 200 STARTING AT 10 10. Plane_type = sflight-planetype.ENDFUNCTION.在這個例子中包括一個selection screen100和一個screen 200。模塊池和通常屏幕之間的接口經過TABLES語句來聲明。功能模塊來處理屏幕並經過參數來輸入輸出數據。若是模塊池中須要內部模塊,能夠經過本地類來實現。若是模塊池屏幕中包含GUI控件,相應的事件處理也應當在模塊池的本地類中實現。在這個簡單的例子中並無screen module。若是你想使用輸入檢查這樣的自動機制,那麼你就要使用這些screen module了。不過要記住在這些module中要輸入儘可能少的代碼而要儘可能去調用本地類的方法。另外考慮到數據的封裝性,應儘可能減小直接操做全局變量。下面的一段代碼演示瞭如何在類flights中使用功能模塊get_plane_type的屏幕。CLASS flights DEFINITION. PUBLIC SECTION.METHOS: constructor,          Change_plane_type. PRIVATE SECTION.    DATA flight TYPE sflight.ENDCLASS.CLASS flights IMPLEMENTATION. METHOD constructor.     DATA: carrid TYPE sflight-carrid,           Connid TYPE sflight-connid,           Fldate TYPE sflight-fldate.     CALL FUNCTION ‘GET_FLIGHT_PARAMETERS’           IMPORTING              Carrid = carrid              Connid = connid              Fldate = fldate.      SELECT SINGLE * FROM sflight                       INTO flight                WHERE carrid = carrid AND                        Connid = connid AND                        Fldate = fldate. ENDMETHOD. METHOD change_plane_type.CALL FUNCTION ‘GET_PLANE_TYPE’      CHANGING plane_type = flight-planetype. ENDMETHOD.ENDCLASS.這個類中的每一個對象表明着表sflight中的一個flight。建立對象時,類的結構方法便會調用功能模塊來取得選擇屏幕上的業務主鍵。方法change_plane_type來處理屏幕200要求輸入plane type,可是在類中沒有任何屏幕邏輯。只 在應用程序中使用ABAP OO並將其與屏幕邏輯分離開來將爲將來表現層技術的變革打下基礎(好比SAP GUI和BSP)。屏幕邏輯和應用邏輯再也不混合在一塊兒,新的表現層的技術變革將限制一些過程的調用。不過有趣的是這種分離在面向過程的程序開發中也能夠是 實現只不過並無強制。簡單例證即是屏幕並不容許被做爲類的組件。因此如今就應當儘可能熟悉這種方式。

相關文章
相關標籤/搜索