From Zero to SAP

[ABAP] 객체지향 프로그래밍 3편 - 인터페이스, 이벤트 심화 본문

ABAP/이론

[ABAP] 객체지향 프로그래밍 3편 - 인터페이스, 이벤트 심화

권쌥 2026. 4. 20. 22:49

1편에서 클래스/메서드/생성자, 2편에서 상속/다형성/Abstract를 다뤘다.

마지막 3편에서는 인터페이스이벤트 심화를 정리한다.
이번 편을 끝으로 ABAP OOP의 핵심 개념이 마무리된다.


목차

  1. 왜 인터페이스가 필요한가?
  2. 인터페이스란?
  3. 인터페이스 구현
  4. 인터페이스 참조와 다형성
  5. 별명 (ALIASES)
  6. 이벤트 심화
  7. 배운 점

1. 왜 인터페이스가 필요한가?

ABAP은 다중 상속을 허용하지 않는다.

이유는 바로 다이아몬드 문제 때문이다.

여러 부모 클래스에서 같은 이름의 메서드를 상속받으면 컴파일러가 어느 쪽을 호출해야 할지 결정할 수 없게 된다.

예를 들어 FlyingAnimalSwimmingAnimal 이 각자 speak() 를 오버라이딩한 상태에서 Duck 이 둘 다 상속받으면, Duckspeak() 는 어느 쪽인지 알 수 없는 것이다.

그러나 다중 상속이 가능하다면 여러 클래스에 들어있는 공통 기능에 접근할 수 있다는 장점도 있다.

이 장점을 살리기 위해 ABAP도 인터페이스를 지원한다.

다이아몬드 문제


2. 인터페이스란?

인터페이스는 사실 순수 추상 클래스다. 말 그대로 구현 내용 없이 선언만으로 이루어진 클래스다.

따라서 추상 클래스의 특징을 그대로 가진다.

  • 객체 직접 생성 불가
  • 반드시 서브클래스가 상속받아 메서드를 구현

클래스와 비슷한 특징도 있다.

  • 전역 또는 지역으로 정의 가능
  • 속성, 메서드, 이벤트 선언 가능 (단, 구현 내용은 없음)

한 가지 중요한 차이는, 인터페이스의 모든 컴포넌트는 무조건 PUBLIC 이다. 접근 제한자를 따로 지정할 필요가 없다.

  클래스 인터페이스
접근 제한자 PUBLIC / PROTECTED / PRIVATE 무조건 PUBLIC
객체 생성 가능 불가
구현 내용 있음 없음
다중 구현 불가 (단일 상속) 가능

3. 인터페이스 구현

선언은 INTERFACE ~ ENDINTERFACE, 구현은 틸트(~) 기호를 사용한다.

" 인터페이스 선언
INTERFACE zif_account.
  METHODS calc
    IMPORTING p1 TYPE i.
  DATA balance TYPE i.
ENDINTERFACE.
" 클래스에서 구현
CLASS zcl_cls1 DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.
    INTERFACES zif_account.        " Java의 implements
ENDCLASS.

CLASS zcl_cls1 IMPLEMENTATION.

  METHOD if_oo_adt_classrun~main.
    zif_account~balance = 300.
    zif_account~calc( p1 = zif_account~balance ).
  ENDMETHOD.

  METHOD zif_account~calc.         " 인터페이스명~메서드명
    out->write( |Deposit: { p1 }| ).
  ENDMETHOD.

ENDCLASS.

 

정리

  • 인터페이스는 반드시 PUBLIC SECTION 에서만 선언
  • 구현할 때 메서드 이름은 인터페이스명~메서드명 형태
  • 속성 접근도 zif_account~balance 처럼 ~ 사용

사실 우리가 ADT에서 계속 써온 if_oo_adt_classrun~main 이 바로 이 패턴이다.

if_oo_adt_classrun 인터페이스의 main 메서드를 구현한 것이다.


4. 인터페이스 참조와 다형성

인터페이스 타입으로 참조변수를 선언하면, 해당 인터페이스를 구현한 어떤 클래스의 객체든 담을 수 있다.

TV 리모컨이든 에어컨 리모컨이든, 리모컨 이라는 공통 타입 하나로 전원 버튼을 누를 수 있는 것과 같다.

" 두 클래스가 같은 인터페이스를 구현
" zcl_cls1 - 입금 계좌
" zcl_cls2 - 출금 계좌

DATA lo_iref TYPE REF TO zif_account.  " 인터페이스 타입으로 선언

DATA(lo_cls1) = NEW zcl_cls1( ).
DATA(lo_cls2) = NEW zcl_cls2( ).

" 같은 참조변수로 다른 클래스 객체에 접근 (다형성!)
lo_iref = lo_cls1.
lo_iref->calc( ).   " cls1의 calc 실행 → Deposit money is: 300

lo_iref = lo_cls2.
lo_iref->calc( ).   " cls2의 calc 실행 → Withdrawal money is: 200-

상속의 업캐스팅과 동일한 개념이다. 인터페이스 참조변수에 구현 클래스 객체를 할당하는 것도 자동 캐스팅이 된다.


5. 별명 (ALIASES)

인터페이스명~메서드명 형태는 코드가 길어질수록 불편하다. ALIASES 로 짧은 별명을 붙일 수 있다.

CLASS zcl_cls1 DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES zif_account.
    ALIASES calc FOR zif_account~calc.  " 별명 선언
ENDCLASS.
" 호출할 때
lo_cls1->zif_account~calc( p1 = 200 ).  " 원래 방식
lo_cls1->calc( p1 = 200 ).              " 별명으로 간단하게

주의사항! ALIASESDEFINITION (선언부) 에서만 사용 가능하다. IMPLEMENTATION 안에서는 사용할 수 없다.


6. 이벤트 심화

1편에서 개념만 봤던 이벤트를 이번엔 제대로 정리한다.

이벤트 종류

  인스턴스 이벤트 정적 이벤트
선언 EVENTS CLASS-EVENTS
트리거 가능 주체 인스턴스 메서드만 모든 메서드
핸들러 등록 SET HANDLER ... FOR ref SET HANDLER ... (FOR 없음)

 

" 인스턴스 이벤트
EVENTS: order_created.

" 정적 이벤트
CLASS-EVENTS: class_event_triggered.

이벤트 작동 3단계

① 이벤트 선언   →   EVENTS: bowl.
② 핸들러 등록   →   SET HANDLER lee->letsgo FOR kim.
③ 이벤트 발생   →   RAISE EVENT bowl.
                           ↓
                 lee->letsgo( ) 자동 실행

볼링 예제로 이해해보면

KIM->GO_BOWL( ) 호출
      ↓
'WAIT A MINUTE~' 출력
      ↓
RAISE EVENT bowl          ← 이벤트 발생 (트리거)
      ↓
LEE->LETSGO( ) 자동 실행  ← SET HANDLER로 등록된 핸들러
      ↓
'OK, LETS GO!!!' 출력

 

비유하자면, 김씨(이벤트 발생자)가 "볼링 가자!" 외치면 이씨(핸들러)가 자동으로 "갑시다!" 응답하는 구조와 같다.


SET HANDLER 방식 3가지

" 1. 특정 인스턴스만
SET HANDLER lo_handler->on_event FOR lo_obj.

" 2. 모든 인스턴스
SET HANDLER lo_handler->on_event FOR ALL INSTANCES.

" 3. 정적 이벤트 (FOR 없음)
SET HANDLER zcl_class=>handle_event.

이벤트 발생 시 동작 규칙

  • RAISE EVENT 가 호출되면 다음 줄로 넘어가기 전에 등록된 핸들러가 전부 실행됨 (동기 처리)
  • 핸들러 안에서 또 이벤트를 발생시키면, 새 핸들러가 먼저 실행됨
  • 무한루프 방지를 위해 최대 64번까지만 반복 실행

실무 활용 패턴

이벤트는 RAP에서 거의 사용하지 않지만, 레거시 코드에서 아래 패턴을 자주 볼 수 있다.

" 데이터 조회 후 없으면 이벤트로 처리하는 패턴
METHOD get_data.
  SELECT * FROM zemplist
    INTO TABLE @gt_itab
    WHERE empcd IN @s_empcd.

  IF sy-subrc <> 0.
    RAISE EVENT e1.     " 데이터 없으면 이벤트 발생
  ELSE.
    display_data( ).    " 데이터 있으면 출력
  ENDIF.
ENDMETHOD.

 

여기서 sy-subrcABAP 시스템 변수로, 마지막 작업의 성공 여부를 담는다.

의미
0 성공
4 SELECT 결과 없음
그 외 작업 실패

Java의 null 체크, 예외 처리와 비슷한 역할이다. ABAP 코드에서 IF sy-subrc <> 0 패턴은 엄청 자주 나오니 눈에 익혀두자.


7. 배운 점

  • 인터페이스는 다중 상속의 단점(다이아몬드 문제)을 피하면서 장점을 살리는 방법이다.
  • 인터페이스 컴포넌트는 무조건 PUBLIC, 구현 시 인터페이스명~메서드명 형태를 사용한다.
  • 인터페이스 참조변수로 다형성을 구현할 수 있다. 상속의 업캐스팅과 동일한 개념이다.
  • ALIASES 로 긴 인터페이스 메서드명을 짧게 줄일 수 있다.
  • 이벤트는 독립적인 클래스 간의 통신 수단이며, RAP에서는 Validation/Determination/Action으로 대체된다.
  • sy-subrc 는 ABAP에서 가장 자주 쓰는 시스템 변수다.

ABAP OOP 시리즈 전체 요약:

주요 내용
1편 클래스, 메서드 파라미터, 생성자, 이벤트 개념
2편 상속, 오버라이딩, 다형성, Abstract/Final, 정적 속성
3편 인터페이스, 인터페이스 참조, 별명, 이벤트 심화

 

개발 환경: Eclipse ADT + SAP BTP Trial
참고 교재: HANA 기반 Easy ABAP 3.0