[JAVA] 인터페이스(interface)의 이해 & 사용 이유

정솔·2023년 8월 1일
1

JAVA

목록 보기
1/1
post-thumbnail

인터페이스란

자바의 인터페이스에 대해 알아보고, 왜 사용하는지 소개해보고자 합니다.
인터페이스는 내용 없는 추상 메서드로만 이뤄져 있습니다. 그렇기에 단독으로 사용될 수 없고 클래스로 꼭 구현해야 합니다.
즉 클래스에서 구현을 강제하는 것입니다.

그래서... 인터페이스를 왜 사용해야하는 걸까요?



인터페이스를 사용하는 이유

1. 클래스 설계시 표준화를 유도할 수 있기 때문입니다.
2. 유지보수할 때 효율이 좋고, 자바의 특징인 다형성을 극대화할 수 있기 때문입니다.

이렇게 말로만 하면 이해하기 쉽지 않습니다. 코드를 보며 왜? 굳이! 인터페이스를 사용하는지 알아보겠습니다.


// Communication interface
public interface Communicatable {
    void 전화걸기(String 번호);
    void 전화받기(String 번호);

    default void 전화거절(String 번호) {
        System.out.println("전화를 거절합니다. 번호: " + 번호);
    }

    static void 문자메시지보내기(String 번호, String 내용) {
        System.out.println("번호 " + 번호 + "로 메시지를 보냅니다. 내용: " + 내용);
    }
}

// Smartphone class
public class Smartphone implements Communicatable {
    @Override
    public void 전화걸기(String 번호) {
        System.out.println("번호 " + 번호 + "로 스마트폰에서 전화를 겁니다.");
    }

    @Override
    public void 전화받기(String 번호) {
        System.out.println("스마트폰으로부터 번호 " + 번호 + "의 전화를 받았습니다.");
    }

    @Override
    public void 전화거절(String 번호) {
        System.out.println("스마트폰으로부터 번호 " + 번호 + "의 전화를 거절했습니다.");
    }
}

// Dumbphone class
public class Dumbphone implements Communicatable {
    @Override
    public void 전화걸기(String 번호) {
        System.out.println("번호 " + 번호 + "로 피처폰에서 전화를 겁니다.");
    }

    @Override
    public void 전화받기(String 번호) {
        System.out.println("피처폰으로부터 번호 " + 번호 + "의 전화를 받았습니다.");
    }
}

// Main class
public class Main {
    public static void main(String[] args) {
        Communicatable smartphone = new Smartphone();
        Communicatable dumbphone = new Dumbphone();

        smartphone.전화걸기("010-1234-5678");
        smartphone.전화받기("010-9876-5432");
        smartphone.전화거절("010-1111-1111");

        dumbphone.전화걸기("02-123-4567");
        dumbphone.전화받기("02-987-6543");
        dumbphone.전화거절("02-2222-2222");

        Communicatable.문자메시지보내기("010-1234-5678", "안녕하세요!");
    }
}

1. 표준화 유도?

위 코드를 보면 Communicatable 인터페이스를 Smartphone 클래스와 Dumbphone 클래스가 implements 키워드를 통해 구현하고 있습니다.

Communicatable 인터페이스는 전화를 걸고, 받고, 거절하는 기능에 대한 표준화된 명세를 정의하고 있습니다. 이 인터페이스를 구현하는 클래스들인 SmartphoneDumbphone는 해당 명세에 따라서 각각의 기능을 구현해야 하는 것이죠. 이를 통해 통신 기능에 대한 일관성 있는 표준을 유지할 수 있습니다.

예를 들어, 다른 곳에서 Communicatable 인터페이스를 사용하는 코드가 있을 때, 해당 코드는 전화걸기, 전화받기, 전화거절 메서드를 호출하기만 하면 됩니다.
어떤 기기가 구현되었는지 상관없이 인터페이스가 제공하는 메서드를 호출함으로써 동일한 기능을 수행할 수 있는 것이지요!


2. 다형성?

위 코드를 보면 Communicatable 인터페이스를 구현한 Smartphone 클래스와 Dumbphone 클래스를 다형성을 이용하여 사용하고 있습니다.

		Communicatable smartphone = new Smartphone();
        Communicatable dumbphone = new Dumbphone();

        smartphone.전화걸기("010-1234-5678");
        dumbphone.전화걸기("02-123-4567");

Communicatable 타입의 변수 smartphonedumbphone는 각각 SmartphoneDumbphone의 인스턴스를 참조하고 있습니다. Communicatable 인터페이스는 전화걸기 메서드를 정의하고 있으므로, 어떤 구현 클래스가 할당되었는지에 상관없이 전화걸기 메서드를 호출할 수 있습니다.

이렇게 인터페이스를 사용하여 다형성을 구현하면, 한 가지 인터페이스를 기반으로 다양한 클래스들을 사용할 수 있습니다. 이는 코드의 유연성과 재사용성을 높여주며, 새로운 구현 클래스를 추가하거나 기존 구현 클래스를 변경해도 다른 부분에 영향을 주지 않고 기능을 확장할 수 있는 장점을 제공합니다!




default 메소드와 static 메소드

default 메소드와 static 메소드는 JAVA8부터 추가된 내용인데요.
더 유연하게 인터페이스를 사용할 수 있게 해줍니다.


- default method

여러분이 참여중인 프로젝트에서 많이 사용되어지고 있는 인터페이스가 있다고 가정해봅시다.
여기에 새로운 추상메소드가 추가된다면 어떨까요?

기존에 존재하던 클래스들에 컴파일 에러가 발생하며,
인터페이스를 사용중인 모든 곳에서 오버라이드 해주어야 할 것입니다.

이런 번거로움을 해결하고자 default 메소드가 있습니다.
default 메소드는 추상메소드와 달리 구현부가 존재합니다.
위 코드에선 전화거절 메서드인 것이지요.

이 default 메소드를 그대로 사용하겠다거나, 사용하지 않으려면 클래스에서 재구현하지 않으면 됩니다.
반대로 default 메소드를 수정해야겠다면 오버라이드하여 재구현하면 되는 것입니다.



- static method

static 메소드는 default 메소드와 달리 재정의 할 수 없습니다. 때문에 인터페이스에서 제공하는 공통적인 기능에 사용되거나, 독립적인 유틸리티 함수들을 구현하는 데 유용합니다.

static 메소드는 인터페이스 이름으로 직접 호출할 수 있습니다. 이런 식으로 말이죠!
인터페이스명.메소드명()

Communicatable.문자메시지보내기("010-1234-5678", "안녕하세요!");

2개의 댓글

comment-user-thumbnail
2023년 8월 1일

좋은 글 감사합니다.

1개의 답글