[Java] 12. 인터페이스(Interface)


인터페이스는 추상메서드의 집합으로 예시로 공통 된 기능을 추상화 하여 프로젝트에 규격화 시켜서 모듈을 결합하므로 느슨한 결합으로 코드의 변경 없이 서비스를 할 수 있다.



1. 인터페이스(interface)란?

  • 인터페이스는 추상메서드의 집합(abstract)이다.
  • 두 객체 간의 연결을 돕는 중간 역할을 하며 클래스마다 독립적인 프로그래밍이 가능하다.
  • 느슨한 결합으로 변경에 유연한 코드가 된다.
  • 자바에서는 클래스를 통한 다중 상속을 지원하지만, 인터페이스를 통해 다중 상속이 가능하다.
  • 인터페이스란 다른 클래스를 작성할 때 기본이 되는 틀을 제공하면서, 다른 클래스 사이의 중간 매개 역할을 한다.
  • 구현된 것이 전혀 없는 설계도(모든 멤버가 public)
  • 인터페이스 조상은 인터페이스만 가능하다.(Object가 최고 조상 아님)


interface 인터페이스이름 {
    //public, abstract 예약어 생략 가능
    public abstract void 추상메서드이름(매개변수);
}



2. 인터페이스와 추상메서드의 차이

  • 추상클래스는 추상 메소드뿐만 아니라 생성자, 필드, 일반 메소드를 가질 수 있다.
  • 인터페이스는 오로지 추상 메소드와 상수만을 가질 수 있다.



3. 인터페이스의 구현

  • 인터페이스에 정의 된 추상 메서드의 구현부를 완성하는 것을 인터페이스 구현이라고 한다.
class 클래스이름 implements 인터페이스이름 {

    public void 추상메서드이름(매개변수) {
        //구현부 구현
    }
}



4. 인터페이스 코딩 예제

더 좋은 기능이 생겼거나 상황이 바뀌어 새로운 형태로 만드는 경우 소스코드를 변경 없이 변경이 용이함.


//인터페이스에서 getData() 공통 기능을 구현하라고 설계
interface I {
    String getData();
}

class X {

    private I i;

    public void setI(I i){
        this.i = i;
    }

    public void getData(){
        String data = i.getData();
        System.out.println("Class Data= " + data);
    }
}

//A에서 getData() 구현
class A implements I {

    @Override
    public String getData() {
        return "A Class Data";
    }
}

//B에서 getData() 구현
class B implements I {

    @Override
    public String getData() {
        return "B Class Data";
    }
}

/**
 * 인터페이스 결합 예제
 */
public class ExInterfaceCombination {

    public static void main(String... args) {

        X x = new X();

        A a = new A();
        B b = new B();

        //X 객체에 A 결합 형태로 구현
        x.setI(a);
        x.getData();
        //X 객체에 B 결합 형태로 구현
        x.setI(b);
        x.getData();

    }
}



5. 인터페이스 배터리 충전 예제

예시로 배터리, 결제 등 여러 벤더사의 공통 된 기능을 추상화 하여 프로젝트에 규격화 시키면
필요한 벤더사나 서비스에 대해서 인터페이스의 결합을 통해서 코드 큰 수정없이 서비스를 할 수 있다.

실제로는 리플렉션을 같이 활용한다.


배터리 충전 예제

/**
 * 인터패이스 BatteryCharge 로 배터리 충전 기능을 설계
 */
interface BatteryChargeType {
    void charging();
}

class PluginBattery {

    private BatteryChargeType batteryChargeType;

    //배터리 충전 타입을 결합
    public void pluginBattery (BatteryChargeType batteryChargeType) {
        this.batteryChargeType = batteryChargeType;
    }

    //배터리 충전 시작
    public void startCharging() {
        batteryChargeType.charging();
    }
}

class DefaultCharge implements BatteryChargeType {
    @Override
    public void charging() {
        System.out.println("배터리 기본 충전 시작");
    }
}

class FastCharge implements BatteryChargeType {
    @Override
    public void charging() {
        System.out.println("배터리 고속 충전 시작");
    }
}

/**
 * 인터페이스 결합 예제 (ExInterfaceCombination.java)
 * - 배터리 교체
 */
public class ExBatteryCharging {

    public static void main(String... args) {

        PluginBattery pluginBattery = new PluginBattery();
        //기본 충전 일때
        pluginBattery.pluginBattery(new DefaultCharge());
        pluginBattery.startCharging();

        //고속 충전 일때
        pluginBattery.pluginBattery(new FastCharge());
        pluginBattery.startCharging();
    }
}



결제 벤더사 예제

//지불결제
interface Payment {
    //결제 요청
    void pay();
    //할인 결제 요청
    void discountPay();
}

class KakaoPay implements Payment {

    @Override
    public void pay() {
        System.out.println("카카오페이 결제 API 호출 처리");
    }

    @Override
    public void discountPay() {
        System.out.println("카카오페이 할인 결제 API 호출 처리");
    }
}

class HyundaiCard implements Payment {

    @Override
    public void pay() {
        System.out.println("현대카드 결제 API 호출 처리");
    }

    @Override
    public void discountPay() {
        System.out.println("현대카드 할인 결제 API 호출 처리");
    }
}


class Pay extends EventPay implements Payment {

    private String paymentType;
    Payment payment;

    @Override
    public void pay() {
        System.out.println("일반 결제 처리");
    }

    @Override
    public void discountPay() {
        System.out.println("일반 할인 결제 처리");
    }
  
    //지불결제 벤더사 선택
    public void setPaymentType(String paymentType) {
        this.paymentType = paymentType;
    }

    //벤더사에 결제 처리 요청
    public Payment getPaymentVendor() {
        Payment payment = new Pay();

        if ("KAKAO_PAY".equals(paymentType)) {
            payment = new KakaoPay();

        } else if ("HYUNDAI_CARD".equals(paymentType)) {
            payment = new HyundaiCard();
        }

        return payment;
    }

}

public class ExInterfacePloy {

    public static void main(String... args) {

        //결제 유형 선택
        Pay pay = new Pay();
        pay.setPaymentType("KAKAO_PAY");

        Payment payment = pay.getPaymentVendor();
        //비즈니스 로직

        payment.pay();
        payment.discountPay();
    }
}