Backend
home
🪜

인터페이스

생성 일시
2025/01/22 10:39
태그
Java
게시일
2025/01/22
최종 편집 일시
2025/02/09 13:26

인터페이스란?

극단적으로 동일한 목적 하에 동일한 기능을 수행하게끔 강제하는 것이 인터페이스의 역할이다.
자바의 다형성을 극대화하여 개발코드 수정을 줄이고 프로그램 유지보수성을 높이기 위해 인터페이스를 사용한다.

인터페이스 사례

교수님이 학생들에게 논문을 작성하라는 과제를 냄
A학생은 PPT로 논문을 11일날 제출
B학생은 EXCEL 2016으로 논문을 12일날 제출
C학생은 EXCEL 2019로 자기만의 색깔을 입혀 표 형식으로 12일날 제출
만약 이렇게 과제를 제출할 경우 교수님은 학생들의 과제를 평가하기 어렵다. 기준이 명확하지 않을 뿐만 아니라 가이드 라인이나 없었기에 이와 같은 문제가 발생한 것이다. 따라서 교수님은 명확한 가이드라인이 있는 논문을 작성하라고 다시 전달해야 한다. 다음과 같이 말이다.
학생들에게 2019.12.12일 18:00까지 홈페이지 본인 교수 홈페이지 제출란을 통해 논문을 제출해야하고 논문 파일 형식은 .PPT이며 10Page 안에 작성을 해야하고 논문 주제는 '블록체인을 활용한 공인인증서' 이다.
Plain Text
복사
⇒ 인터페이스란? - 극단적으로 동일한 목적 하에 동일한 기능을 보장
⇒ 어떻게? 자바의 다형성을 이용하여 개발코드 수정을 줄이고 유지보수성을 높임

인터페이스 문법, 다형성 이해

인터페이스는 interface 키워드를 통해 선언할 수 있으며 implements 키워드를 통해 일반 클래스에서 인터페이스를 구현할 수 있다.
JAVA8 이전가지는 상수, 추상메소드만 선언 가능했지만, JAVA8부터 디폴트 메소드, 정적 메소드가 추가되었다.
//상수 타입 상수명 =; //추상 메소드 타입 메소드명(매개변수, ... ); //디폴트 메소드 default 타입 메소드명(매개변수, ... ){ //구현부 } //정적 메소드 static 타입 메소드명(매개변수) { //구현부 } }
Java
복사
상수: 인터페이스에서 값을 정해줄테니 함부로 바꾸지 말고 제공해주는 값만 참조해라 (절대적)
추상메소드: 가이드만 줄테니 추상메소드를 오버라이팅해서 재구현해라 (강제적)
디폴트메소드: 인터페이스에서 기본적으로 제공해주지만, 맘에 안들면 각자 구현해서 써라 (선택적)
정적메소드: 인터페이스에서 제공해주는 것으로 무조건 사용
참고로 절대적이란 아무것도 손댈 수 없다는 것을 의미하며, 강제적이란 인터페이스를 implements하지 않으면 피할수는 있다는 의미이다. 강제성이 있다고 하여 절대적인 것은 아니다.
예시
대한민국에서 은행 사업을 하려면, 금융결제원에서 정의한 어떤 가이드를 따라야한다고 가정하고, Bank 라는 이름으로 인터페이스를 만들었다.
이제 어느 은행이든 은행 시스템은 운영하려면 Bank라는 인터페이스 가이드에 맞게 구현해야한다.
인출메소드, 입금메소드는 각 은행에서 오버라이딩 해서 재구현을 해야하며 블록체인 인증 메소드는 무조건 금융결제원에서 제공해주는 메소드를 사용해야 한다. 따라서 정적메소드로 구현하여 오버라이딩을 할 수 없게 만들었다. (그냥 가져다가 쓰라는 소리)
public interface Bank { //상수 (최대 고객에게 인출해 줄 수 있는 금액 명시) public int MAX_INTEGER = 10000000; //추상메소드(인출하는 메소드) void withDraw(int price); //추상메소드(입금하는 메소드) void deposit(int price); //JAVA8에서 가능한 defualt 메소드(고객의 휴면계좌 찾아주는 메소드 : 필수구현은 선택사항) default String findDormancyAccount(String custId){ System.out.println("**금융개정법안 00이후 고객의 휴면계좌 찾아주기 운동**"); System.out.println("**금융결제원에서 제공하는 로직**"); return "00은행 000-000-0000-00"; } //JAVA8에서 가능한 정적 메소드(블록체인 인증을 요청하는 메소드) static void BCAuth(String bankName){ System.out.println(bankName+" 에서 블록체인 인증을 요청합니다."); System.out.println("전 금융사 공통 블록체인 로직 수행"); } }
Java
복사
디폴트 메소드란 무엇인가?
예시
금융결제원에서 이미 인터페이스를 각 은행사에 가이드 하였고 정상적으로 서비스가 되고 있는데 갑자기 금융 트렌드가 바뀌어서 고객의 휴면계좌를 찾아주는 서비스를 정부에서 점진적으로 도입하라고 지시하였다면…
추상메소드를 그냥 추가해서 다시 가이드 하면 되지 않을까 생각할 수도 있지만 쉽지 않다. 각 은행사마다 개발 및 운영환경이 다르고 휴면계좌 찾아주기 신규 프로세스를 도입하는데 있어 은행사마다 개발 기간이 모두 상이하기에 조금은 러프한 메소드를 추가해줘야 한다. 만약 추상메소드를 인터페이스에서 추가한다면, 이를 implements한 모든 클래스에서 강제적으로 추상 메소드를 구현해야 하며 구현하지 않을 경우 전부 에러가 난다.
하지만 디폴트 메소드를 정의하여 기본 구현부를 제공하고 만약에 기본 구현부가 마음에 들지 않는다 하더라도 각자가 오버라이딩을 통해 재구현할 수 있도록 선택적인 메소드를 가이드한다면 시스템 운영 및 유지보수성이 확보될 것이다. ⇒ 쉽게 말해 이미 운영되고 있는 시스템에서 추가 요건으로 인해 불가피하게 반영을 해야 할 때 디폴트메소드르 쓰면 효과적이란 의미이다.
KB 은행, SH은행은 규격화된 Bank 인터페이스를 통해 각자에 맞는 스타일대로 은행 인출/입금 서비스를 제공한다.
public class KBBank implements Bank{ @Override public void withDraw(int price) { System.out.print("KB은행만의 인출 로직..."); if (price < Bank.MAX_INTEGER){ System.out.println(price+" 원을 인출한다."); } else { System.out.println(price+" 원을 인출실패."); } } @Override public void deposit(int price) { System.out.println("KB은행만의 입금 로직..."+price+" 원을 입금한다."); } }
Java
복사
KB은행은 휴면계좌 찾아주기 메소드를 재구현하지 않았다. 즉 금융결제원이 제공해주는 메소드를 사용하겠다는 뜻이거나 혹은 아직 사용하지 않는다라고 이해하면 된다.
public class SHBank implements Bank{ @Override public void withDraw(int price) { System.out.println("SH은행만의 인출 로직..."); if(price < Bank.MAX_INTEGER){ System.out.println(price+" 원을 인출한다."); }else{ System.out.println(price+" 원을 인출실패."); } } @Override public void deposit(int price) { System.out.println("SH은행만의 입금 로직..."+price+" 원을 입금한다."); System.out.println("SH은행은 별도의 후행처리 작업을 따로 한다."); } //JAVA8에서 가능한 defualt 메소드(고객의 휴면계좌 찾아주는 메소드) @Override public String findDormancyAccount(String custId){ System.out.println("**금융개정법안 00이후 고객의 휴면계좌 찾아주기 운동**"); System.out.println("*SH은행만의 로직 적용*"); return "00은행 000-000-0000-00"; } }
Java
복사
하지만 SH 은행은 휴면계좌 찾아주기 메소드를 재정의하여 SH은행사 만의 휴면계좌 찾아주기 로직을 재구현했다.
public class KakaoBank{ public void kakaoWithDraw(int price) { System.out.print("Kakao은행만의 인출 로직..."); System.out.println(price+" 원을 인출한다."); } public void kakaoDeposit(int price) { System.out.println("Kakao은행만의 입금 로직..."+price+" 원을 입금한다."); } public void kakaoFindDormancyAccount(){ System.out.println("kakao은행만의 휴면계좌 찾아주기 로직"); } }
Java
복사
마지막으로 카카오뱅크 같은 경우 인터페이스를 implements 하지 않은 채 자신만의 메소드를 구현했다. 어떤 문제점이 있을까? 당연히 금융결제원에서 제공해주는 그 어떠한 서비스도 사용할 수 없을 뿐만 아니라 호환성도 없으며 연동 역시 불가능할 것이다.
public class Main { public static void main(String[] args) { Bank bank = new KBBank(); bank.withDraw(100); bank.deposit(100); bank.findDormancyAccount("763231"); Bank.BCAuth("KBBank"); System.out.println("\n*************인스턴스 교체!!***************\n"); bank = new SHBank(); bank.withDraw(100); bank.deposit(100); bank.findDormancyAccount("4311"); Bank.BCAuth("SHBank"); System.out.println("\n*************카카오은행 연동 실패!!***************\n"); //호환성 불가 /* bank = new KakaoBank(); bank.withDraw(100); bank.deposit(100); bank.findDormancyAccount("4311"); */ System.out.println("\n*************대학교 주은행 교체!!***************\n"); bank = new KBBank(); //new KBBank(); bank.withDraw(20000); bank.deposit(1000); bank.findDormancyAccount("855512"); Bank.BCAuth("SHBank"); } }
Java
복사
위의 메인 소스를 보면, bank = new kakaoBank(); 부분에서 type mismatch 에러가 날 것이다. 또한, 자바의 다형성을 극대화 하여 개발 코드 수정을 줄일 수 있다고 했는데 어떤 부분에서 가능한 것일까?
만약에 이 메인함수가 특정 대학교에 등록금 인출, 입금 등의 업무와 관련 있는 코드라고 가정해보자. 대학교는 간혹 등록금 납부 주관 은행을 교체하기도 한다. 물론 가상계좌를 통해 납입하지만 주은행을 변경하게 되면 대학교 등록금 납부 시스템에 기존은행에서 교체할 은행으로 변경을 해줘야한다. 이 경우에 간단하게 인스턴스만 바꿔주면 호환성이 보장된 상태에서 동일한 기능을 수행할 수 있을 것이다.
정리
인터페이스는 추상메소드와 상수를 통해 강력한 강제성을 가지게 하여 인터페이스를 implements 한 클래스가 동일한 동작을 수행하도록 보장한다. 또 JAVA8 부터 디폴트 메소드를 허용하면서 추가요건에 대한 대처를 할 수 있도록 유연성을 확보해준다.