【轉載】ABAP面向物件(Object Orientation)程式設計4-類的構造方法(constructor method)
建構函式就是CREATE OBJECT的時候會自動呼叫的方法(method).分為靜態和非靜態兩種。
1,靜態構造方法
語法:
1 |
CLASS-METHODS class_constructor. |
靜態的建構函式是每個類都已具有的方法,但我們可以通過重定義來完成某些初始化工作
靜態的構造器只在程式中被呼叫一次,即第一次作用該類呼叫時,且不能被程式顯示地呼叫
該方法也必須在公共部分採用CLASS-METHODS宣告,其名稱必須是class_constructor,且沒有引數(因為不能被顯示的呼叫)
並且在此方法裡只能訪問類的靜態屬性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
REPORT ztest_oo_static_constructor. CLASS cl_test DEFINITION. PUBLIC SECTION. CLASS-METHODS: class_constructor . ENDCLASS. CLASS cl_test IMPLEMENTATION. METHOD: class_constructor. WRITE:/ '類已載入'. ENDMETHOD. ENDCLASS. START-OF-SELECTION. DATA: go_test TYPE REF TO cl_test. "在每一次使用類時,靜態的建構函式會自動呼叫 CREATE OBJECT go_test. |
執行後:
2,非靜態構造方法
語法:
1 2 3 |
METHODS constructor [FINAL] [IMPORTING parameters [PREFERRED PARAMETER p]] [{RAISING|EXCEPTIONS} exc1 exc2 ...]. |
建構函式的名是固定的,即為constructor
構造方法預設就是FINAL的,所以沒有必要加
構造器必須放在Public段中進行宣告
構造方法中不能包含任何形式的輸出引數和返回值
如果在物件建立並呼叫構造方法的過程中出現異常,則該物件將被刪除
建構函式沒有輸出引數,只有輸入引數,且無返回值
每個類都會有一個預設的無參構造器,但如果重新定義了構造器,則會覆蓋預設構造器
在類的建立過程中,有兩個特殊的方法,一個是例項的建構函式constructor,該方法在例項建立時隱式的呼叫;另一個方法是類建構函式class_constructor(靜態構造方法),該方法在第一次訪問類時被呼叫,且只調用一次。
如果某個類繼承了別的類(Object除外),這個某個類又重新定義了構造器,則一定要在構造器中明確使用super->constructor方法來呼叫一下父類構造器(否則編輯不通過),只有這樣才能保證整個物件被完整地構造出來,因為子類只能正確地構造出屬於自己的那部分屬性,對於從基類繼承來的那部分屬性要呼叫基類中的構造方法來完成。在呼叫父構造器前,只能訪問父類中靜態的元件,只有在呼叫了父類構造器後,才能去訪問父中的例項元件。
如果在一個子類裡重寫了預設建構函式constructor,則在實現時一定要明確的使用CALL METHOD super->constructor.呼叫一下父類的建構函式,但不一定是在第一句進行呼叫。
如果某個類重寫了父類某個方法,則在父類構造器中如果呼叫該方法,呼叫到的方法還是父類的方法,而不是被重寫後的子類方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
REPORT ztest_oo_constructor. CLASS cl_father DEFINITION. PUBLIC SECTION. METHODS : constructor, method_1, method_2. ENDCLASS. CLASS cl_son DEFINITION INHERITING FROM cl_father. PUBLIC SECTION. METHODS : constructor, method_1 REDEFINITION, method_2 REDEFINITION. ENDCLASS. CLASS cl_father IMPLEMENTATION. METHOD: constructor. "呼叫的是父類中的方法,而不是子類被重寫的方法, me->method_1( ). ENDMETHOD. METHOD: method_1. WRITE: / 'father~method_1'. "即使不是在父類構造器中呼叫被重寫方法也是這樣的, me->method_2( ). ENDMETHOD. METHOD: method_2. WRITE: / 'father~method_2'. ENDMETHOD. ENDCLASS. CLASS cl_son IMPLEMENTATION. METHOD: constructor. super->constructor( ). SKIP. me->method_1( ). ENDMETHOD. METHOD: method_1. WRITE: / 'son~method_1'. me->method_2( ). ENDMETHOD. METHOD: method_2. WRITE: / 'son~method_2'. ENDMETHOD. ENDCLASS. START-OF-SELECTION. DATA: go_object TYPE REF TO cl_father. CREATE OBJECT go_object TYPE cl_son. SKIP. go_object->method_1( ). |
另外,不能在構造器中呼叫抽象方法,所以要想在父類的方法中回撥到時子類重定義方法,該被重寫的方法一定要是父類中定義的抽象方法,這與設計模式中的模板方法設計模式是相當的,以下是使用ABAP面向物件來實現模板方法設計模式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
REPORT ztest_oo_constructor_me. CLASS cl_father DEFINITION ABSTRACT. PUBLIC SECTION. METHODS: method1, method2 ABSTRACT. ENDCLASS. CLASS cl_son DEFINITION INHERITING FROM cl_father. PUBLIC SECTION. METHODS: method2 REDEFINITION. ENDCLASS. CLASS cl_father IMPLEMENTATION. METHOD: method1. "模板模式:在父類中回撥子類實現的父類中所定義的抽象方法 me->method2( ). ENDMETHOD. ENDCLASS. CLASS cl_son IMPLEMENTATION. METHOD: method2."實現父類中定義的抽象方法 WRITE: / 'son~m2'. ENDMETHOD. ENDCLASS. START-OF-SELECTION. DATA: go_object TYPE REF TO cl_father. CREATE OBJECT go_object TYPE cl_son. SKIP. go_object->method1( )."呼叫繼承過來的父類方法 |
3,簡單的例子程式碼
ABAP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
REPORT ZTEST_OO_CONSTRUCTOR. *---------------------------------------------------------------------* * CLASS cl_vehicle DEFINITION *---------------------------------------------------------------------* * *---------------------------------------------------------------------* CLASS cl_vehicle DEFINITION. PUBLIC SECTION. METHODS: accelerate IMPORTING rate TYPE i, constructor IMPORTING i_speed TYPE i, show_speed. PRIVATE SECTION. DATA speed TYPE i VALUE 0. ENDCLASS. "cl_vehicle DEFINITION *&---------------------------------------------------------------------* *& Class (Implementation) cl_vehicle *&---------------------------------------------------------------------* * Text *----------------------------------------------------------------------* CLASS cl_vehicle IMPLEMENTATION. METHOD accelerate. speed = speed + rate. ENDMETHOD. "accelertate METHOD show_speed. WRITE / speed. ENDMETHOD. "show_speed METHOD constructor. speed = i_speed. WRITE: 'constructor i_speed = ',speed. ENDMETHOD. "constructor ENDCLASS. "cl_vehicle DATA o_vehicle TYPE REF TO cl_vehicle. START-OF-SELECTION. CREATE OBJECT o_vehicle EXPORTING i_speed = 4. CALL METHOD o_vehicle->accelerate EXPORTING rate = 2. CALL METHOD o_vehicle->show_speed. |
執行結果: