セクション 8 / 11

ABAPオブジェクト指向

ABAPオブジェクトのクラス定義、継承とインタフェース、静的と動的の違い、そして例外クラスの使い方を解説します。

目次を開く

ABAPオブジェクトは、1999年にABAPへ導入されたオブジェクト指向の機能です。現在のABAP開発では、これが標準的な書き方となっています。

クラスの定義

ABAPのクラスは、定義部(DEFINITION)と実装部(IMPLEMENTATION)に分かれています。

クラスの基本構造
CLASS lcl_order DEFINITION.

  PUBLIC SECTION.
    METHODS constructor
      IMPORTING iv_order_id TYPE vbeln.

    METHODS get_total
      RETURNING VALUE(rv_total) TYPE p LENGTH 8 DECIMALS 2.

    CLASS-METHODS create_from_db
      IMPORTING iv_order_id      TYPE vbeln
      RETURNING VALUE(ro_order)  TYPE REF TO lcl_order.

  PROTECTED SECTION.
    METHODS calculate_tax
      RETURNING VALUE(rv_tax) TYPE p LENGTH 8 DECIMALS 2.

  PRIVATE SECTION.
    DATA mv_order_id TYPE vbeln.
    DATA mt_items    TYPE ty_items.

ENDCLASS.

CLASS lcl_order IMPLEMENTATION.

  METHOD constructor.
    mv_order_id = iv_order_id.
  ENDMETHOD.

  METHOD get_total.
    LOOP AT mt_items INTO DATA(ls_item).
      rv_total = rv_total + ls_item-amount.
    ENDLOOP.
  ENDMETHOD.

ENDCLASS.
可視性セクション
セクションアクセス範囲
PUBLICどこからでもアクセス可能
PROTECTED自クラスと継承したクラスからアクセス可能
PRIVATE自クラス内からのみアクセス可能

インスタンスと静的

ABAPでは、インスタンスに属するものと、クラス自体に属するもの(静的)を、キーワードで区別します。

種類キーワードアクセス演算子
インスタンス属性DATAobj->attr
静的属性CLASS-DATAclass=>attr
インスタンスメソッドMETHODSobj->method( )
静的メソッドCLASS-METHODSclass=>method( )
インスタンスの生成と使用
" 従来の書き方
DATA lo_order TYPE REF TO lcl_order.
CREATE OBJECT lo_order
  EXPORTING iv_order_id = '0000012345'.

" 現代的な書き方(7.4以降)
DATA(lo_order) = NEW lcl_order( iv_order_id = '0000012345' ).

" メソッド呼び出し
DATA(lv_total) = lo_order->get_total( ).

" 静的メソッド呼び出し(インスタンス不要)
DATA(lo_new) = lcl_order=>create_from_db( '0000012345' ).

継承

継承とメソッドの再定義
CLASS lcl_rush_order DEFINITION
  INHERITING FROM lcl_order.

  PUBLIC SECTION.
    METHODS get_total REDEFINITION.

ENDCLASS.

CLASS lcl_rush_order IMPLEMENTATION.
  METHOD get_total.
    " 親クラスの処理を呼ぶ
    rv_total = super->get_total( ).
    " 特急料金を加算
    rv_total = rv_total * '1.2'.
  ENDMETHOD.
ENDCLASS.

ABAPは単一継承のみをサポートします。複数の親を持つことはできません。複数の振る舞いを組み合わせたい場合は、インタフェースを使います。

インタフェース

インタフェースの定義と実装
INTERFACE lif_printable.
  METHODS print.
ENDINTERFACE.

CLASS lcl_invoice DEFINITION.
  PUBLIC SECTION.
    INTERFACES lif_printable.
ENDCLASS.

CLASS lcl_invoice IMPLEMENTATION.
  METHOD lif_printable~print.
    WRITE: / '請求書を印刷します'.
  ENDMETHOD.
ENDCLASS.

" インタフェース参照で扱う
DATA lo_printable TYPE REF TO lif_printable.
lo_printable = NEW lcl_invoice( ).
lo_printable->print( ).

インタフェースを使うと、実装クラスが何であれ同じように扱えます。「印刷できるもの」として請求書も納品書も同じコードで処理できる——これがポリモーフィズムです。テストの際にモックオブジェクトへ差し替えられるという利点もあります。

例外クラス

ABAPオブジェクトでは、例外もクラスとして扱います。従来のEXCEPTIONS(sy-subrcで判定)より、はるかに詳細な情報を伝えられます。

例外処理
" 例外の送出
METHOD get_customer.
  SELECT SINGLE * FROM kna1 INTO @DATA(ls_kna1)
    WHERE kunnr = @iv_kunnr.

  IF sy-subrc <> 0.
    RAISE EXCEPTION TYPE zcx_customer_not_found
      EXPORTING customer_id = iv_kunnr.
  ENDIF.
ENDMETHOD.

" 例外の捕捉
TRY.
    DATA(ls_customer) = lo_service->get_customer( '0000001000' ).

  CATCH zcx_customer_not_found INTO DATA(lx_notfound).
    MESSAGE lx_notfound->get_text( ) TYPE 'E'.

  CATCH cx_root INTO DATA(lx_root).
    " 想定外のエラー
    MESSAGE lx_root->get_text( ) TYPE 'E'.

  CLEANUP.
    " 例外発生時の後始末
ENDTRY.
例外クラスの基底
クラス性質
CX_STATIC_CHECK宣言必須。呼び出し元が必ず処理する
CX_DYNAMIC_CHECK宣言不要。実行時にチェック
CX_NO_CHECK宣言も捕捉も不要。致命的エラー向け

📖 わからない用語は SAP用語辞典 で調べられます。

理解度チェック

このセクションの内容を確認しましょう。

確認問題 1

ABAPクラスで、外部から直接アクセスできる可視性セクションはどれか。

確認問題 2

ABAPではクラスの継承(INHERITING FROM)がサポートされている。

確認問題 3

インスタンスを生成せずに呼び出せるメソッドの種類はどれか。

確認問題 4

ABAPのクラスは多重継承(複数の親クラスからの継承)をサポートしている。

確認問題 5

ABAPでオブジェクト(インスタンス)を生成するための命令はどれか。

確認問題 6

ABAPのインターフェースの説明として正しいものはどれか。