From Zero to SAP
[ABAP] 객체지향 프로그래밍 3편 - 인터페이스, 이벤트 심화 본문
1편에서 클래스/메서드/생성자, 2편에서 상속/다형성/Abstract를 다뤘다.
마지막 3편에서는 인터페이스와 이벤트 심화를 정리한다.
이번 편을 끝으로 ABAP OOP의 핵심 개념이 마무리된다.
목차
1. 왜 인터페이스가 필요한가?
ABAP은 다중 상속을 허용하지 않는다.
이유는 바로 다이아몬드 문제 때문이다.
여러 부모 클래스에서 같은 이름의 메서드를 상속받으면 컴파일러가 어느 쪽을 호출해야 할지 결정할 수 없게 된다.
예를 들어 FlyingAnimal 과 SwimmingAnimal 이 각자 speak() 를 오버라이딩한 상태에서 Duck 이 둘 다 상속받으면, Duck 의 speak() 는 어느 쪽인지 알 수 없는 것이다.
그러나 다중 상속이 가능하다면 여러 클래스에 들어있는 공통 기능에 접근할 수 있다는 장점도 있다.
이 장점을 살리기 위해 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 ). " 별명으로 간단하게
주의사항! ALIASES 는 DEFINITION (선언부) 에서만 사용 가능하다. 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-subrc 는 ABAP 시스템 변수로, 마지막 작업의 성공 여부를 담는다.
| 값 | 의미 |
|---|---|
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