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方法。