CodeGym /Java Blog /무작위의 /Java에서 인터페이스가 필요한 이유
John Squirrels
레벨 41
San Francisco

Java에서 인터페이스가 필요한 이유

무작위의 그룹에 게시되었습니다
안녕! 오늘 우리는 Java의 중요한 개념인 인터페이스에 대해 이야기할 것입니다. 이 단어는 아마 여러분에게 친숙할 것입니다. 예를 들어 대부분의 컴퓨터 프로그램과 게임에는 인터페이스가 있습니다. 넓은 의미에서 인터페이스는 상호 작용하는 두 당사자를 연결하는 일종의 '원격 제어'입니다. 일상 생활에서 인터페이스의 간단한 예는 TV 리모컨입니다. 사람과 TV라는 두 물체를 연결하고 볼륨을 높이거나 낮추고, 채널을 전환하고, TV를 켜거나 끄는 등 서로 다른 작업을 수행합니다. 한 당사자(사람)는 두 번째 당사자가 작업을 수행하도록 하려면 인터페이스에 액세스(리모컨의 버튼 누름)해야 합니다. 예를 들어 TV를 다음 채널로 변경합니다. 게다가 사용자는 TV가 어떻게 구성되어 있는지 또는 채널 변경 프로세스가 내부적으로 어떻게 구현되어 있는지 알 필요가 없습니다. 사용자가 액세스할 수 있는 유일한 것은 인터페이스입니다. 주요 목표는 원하는 결과를 얻는 것입니다. 이것이 프로그래밍 및 Java와 어떤 관련이 있습니까? Everything :) 인터페이스를 만드는 것은 일반 클래스를 만드는 것과 매우 비슷하지만 대신클래스 , 인터페이스라는 단어를 나타냅니다 . 가장 간단한 Java 인터페이스를 살펴보고 작동 방식과 필요한 이유를 살펴보겠습니다.

public interface CanSwim {

     public void swim();
}
CanSwim 인터페이스를 만들었습니다 . 리모컨과 약간 비슷하지만 하나의 '버튼'이 있습니다. 바로 swim() 메서드입니다. 하지만 이 리모콘을 어떻게 사용합니까? 이렇게 하려면 방법, 즉 원격 제어 버튼을 구현해야 합니다. 인터페이스를 사용하려면 프로그램의 일부 클래스에서 메서드를 구현해야 합니다. 개체가 '수영할 수 있는' 클래스를 발명해 봅시다. 예를 들어 Duck 클래스는 다음과 같습니다.

public class Duck implements CanSwim {

    public void swim() {
        System.out.println("Duck, swim!");
    }

    public static void main(String[] args) {

        Duck duck = new Duck();
        duck.swim();
    }
}
"여기서 무엇을 볼 수 있습니까? Duck 클래스는 implements 키워드에 의해 CanSwim 인터페이스 와 '연결'됩니다 . 유사한 메커니즘을 사용하여 상속을 통해 두 클래스를 연결했지만 이 경우 확장이라는 단어를 사용했음을 기억할 수 있습니다. 완전한 명료성으로 ' public class Duck implements CanSwim '을 문자 그대로 'The public Duck class implements the CanSwim interface'로 번역할 수 있습니다. 이는 인터페이스와 연결된 클래스가 해당 메서드를 모두 구현해야 함을 의미합니다 . 인터페이스 , 메서드 , 논리가 포함되어 있습니다. 이것은 필수 요구 사항입니다. 그냥 작성하면DuckCanSwimswim()public class Duck implements CanSwimswim()클래스에 메서드를 생성하지 않으면 Duck컴파일러에서 오류가 발생합니다. Duck은 추상이 아니며 CanSwim에서 추상 메서드 swim()을 재정의하지 않습니다. 이유는 무엇입니까? 왜 이런 일이 발생합니까? TV를 예로 들어 오류를 설명하면 채널을 변경할 수 없는 '채널 변경' 버튼이 있는 TV 리모컨을 누군가에게 건네는 것과 같습니다. 원하는 만큼 버튼을 누를 수 있지만 작동하지 않습니다. 리모컨은 자체적으로 채널을 변경하지 않습니다. 복잡한 채널 변경 프로세스를 구현하는 TV에 신호만 보냅니다. 우리 오리도 마찬가지입니다. 인터페이스를 사용하여 호출할 수 있도록 오리는 수영하는 방법을 알아야 합니다 CanSwim. 방법을 모른다면,CanSwim인터페이스는 사람과 프로그램이라는 두 당사자를 연결하지 않습니다. 그 사람은 프로그램 내에서 수영 swim()하는 방법을 사용할 수 없습니다 . Duck이제 인터페이스가 무엇인지 더 명확하게 이해할 수 있습니다. 인터페이스는 인터페이스를 구현하는 클래스가 가져야 하는 동작을 설명합니다. '행동'은 방법의 모음입니다. 여러 개의 메신저를 만들고 싶다면 가장 쉬운 방법은 인터페이스를 만드는 것입니다 Messenger. 모든 메신저에게 필요한 것은 무엇입니까? 기본적으로 메시지를 주고받을 수 있어야 합니다.

public interface Messenger{

     public void sendMessage();

     public void getMessage();
}
이제 해당 인터페이스를 구현하는 메신저 클래스를 간단히 만들 수 있습니다. 컴파일러 자체는 클래스에서 구현하도록 '강제'합니다. 전보:

public class Telegram implements Messenger {

    public void sendMessage() {

        System.out.println("Sending a Telegram message!");
    }

     public void getMessage() {
         System.out.println("Receiving a Telegram message!");
     }
}
왓츠앱:

public class WhatsApp implements Messenger {

    public void sendMessage() {

        System.out.println("Sending a WhatsApp message!");
    }

     public void getMessage() {
         System.out.println("Reading a WhatsApp message!");
     }
}
바이버:

public class Viber implements Messenger {

    public void sendMessage() {

        System.out.println("Sending a Viber message!");
    }

     public void getMessage() {
         System.out.println("Receiving a Viber message!");
     }
}
이것은 어떤 이점을 제공합니까? 그 중 가장 중요한 것은 느슨한 결합입니다. 클라이언트 데이터를 수집하는 프로그램을 설계한다고 상상해 보십시오. 클래스 Client에는 클라이언트가 사용 중인 특정 메신저를 나타내는 필드가 반드시 필요합니다. 인터페이스가 없으면 이상하게 보일 것입니다.

public class Client {

    private WhatsApp whatsApp;
    private Telegram telegram;
    private Viber viber;
}
세 개의 필드를 만들었지만 클라이언트는 하나의 메신저만 가질 수 있습니다. 우리는 단지 어느 것을 모릅니다. 따라서 클라이언트와 통신할 수 있도록 클래스에 모든 가능성을 추가해야 합니다. null그 중 하나 또는 두 개는 항상 프로그램에서 전혀 필요하지 않은 것으로 밝혀졌습니다 . 대신 인터페이스를 사용하는 것이 좋습니다.

public class Client {

    private Messenger messenger;
}
이것은 느슨한 결합의 예입니다! 클래스 에 특정 메신저 클래스를 지정하는 대신 Client클라이언트에 메신저가 있음을 나타냅니다. 프로그램이 실행되는 동안 어느 것이 정확히 결정될 것입니다. 하지만 이를 위해 인터페이스가 필요한 이유는 무엇입니까? 언어에 추가된 이유는 무엇입니까? 좋은 질문이고 올바른 질문입니다! 일반 상속을 사용하여 동일한 결과를 얻을 수 없습니까? 클래스 Messenger를 부모로, Viber, TelegramWhatsApp자식으로. 실제로 가능합니다. 하지만 걸림돌이 하나 있습니다. 이미 알고 있듯이 Java에는 다중 상속이 없습니다. 그러나 여러 인터페이스에 대한 지원이 있습니다. 클래스는 원하는 만큼 많은 인터페이스를 구현할 수 있습니다. Smartphone하나의 클래스가 있다고 상상해보십시오.App필드는 스마트폰에 설치된 앱을 나타냅니다.

public class Smartphone {

    private App app;
}
물론 앱과 메신저는 비슷하지만 여전히 다른 것입니다. 메신저의 모바일 및 데스크톱 버전이 있을 수 있지만 앱은 구체적으로 모바일 앱을 나타냅니다. Telegram여기에 거래가 있습니다. 상속을 사용하면 클래스 에 개체를 추가할 수 없습니다 Smartphone. 결국 클래스는 와 !를 Telegram동시에 상속할 수 없습니다. 그리고 우리는 이미 그것을 상속하도록 만들고 클래스 에 추가했습니다 . 그러나 클래스는 두 인터페이스를 모두 쉽게 구현할 수 있습니다! 따라서 클래스에 개체를 로 줄 수 있고 클래스 에 로 줄 수 있습니다 . 방법은 다음과 같습니다. AppMessengerMessengerClientTelegramClientTelegramMessengerSmartphoneApp

public class Telegram implements Application, Messenger {

    // ...methods
}

public class Client {

    private Messenger messenger;

    public Client() {
        this.messenger = new Telegram();
    }
}


public class Smartphone {

    private Application application;

    public Smartphone() {
        this.application = new Telegram();
    }
}
이제 우리는 Telegram우리가 원하는 방식으로 클래스를 사용하고 있습니다. 어떤 곳에서는 App. 다른 곳에서는 Messenger. 인터페이스 메소드가 항상 '비어 있음', 즉 구현이 없다는 점을 이미 알고 계실 것입니다. 그 이유는 간단합니다. 인터페이스는 동작을 설명하지만 구현하지는 않습니다. '인터페이스를 구현하는 모든 개체는 CanSwim수영할 수 있어야 합니다': 인터페이스가 알려주는 전부입니다. 물고기, 오리, 말이 헤엄치는 구체적인 방식은 Fish, Duck, 및Horse인터페이스가 아닌 클래스. 채널을 바꾸는 것이 TV의 몫인 것처럼. 리모컨은 이를 위한 버튼을 제공합니다. 그러나 흥미로운 추가 기능이 Java 8에 등장했습니다. 바로 기본 메서드입니다. 예를 들어 인터페이스에는 10개의 메서드가 있습니다. 그들 중 9개는 다른 클래스에서 다른 구현을 가지고 있지만 하나는 모두에 대해 동일하게 구현됩니다. 이전에는 Java 8 이전에는 인터페이스 메서드에 구현이 전혀 없었습니다. 컴파일러에서 즉시 오류가 발생했습니다. 이제 다음과 같이 할 수 있습니다.

public interface CanSwim {

   public default void swim() {
       System.out.println("Swim!");
   }

   public void eat();

   public void run();
}
키워드 를 사용하여 default기본 구현으로 인터페이스 메서드를 만들었습니다. . eat()_ run()_ CanSwim_ 메서드 를 사용하여 이 작업을 수행할 필요는 없습니다 swim(). 구현은 모든 클래스에서 동일합니다. 그건 그렇고, 눈치채지 못하더라도 이전 작업에서 이미 인터페이스를 접했습니다 :) 다음은 생생한 예입니다. 및 인터페이스 Java에서 인터페이스가 필요한 이유 - 2로 작업했습니다 ! 보다 정확하게는 , , 등 의 구현으로 작업했습니다. 동일한 다이어그램은 한 클래스가 동시에 여러 인터페이스를 구현하는 예를 명확하게 보여줍니다. 예를 들어 및ListSetArrayListLinkedListHashSetLinkedListListDeque(양단 대기열) 인터페이스. Map인터페이스 또는 그 구현 에 익숙합니다 HashMap. 그런데 이 다이어그램은 기능을 보여줍니다. 인터페이스는 다른 인터페이스를 상속할 수 있습니다. 인터페이스 SortedMap는 상속하는 Map반면 Deque상속합니다 Queue. 이는 한 인터페이스가 다른 인터페이스의 확장 버전인 인터페이스 간의 관계를 표시하려는 경우에 필요합니다. 인터페이스 의 예를 살펴보겠습니다 Queue. 아직 검토하지 않았습니다.Queues, 하지만 다소 단순하고 매장의 일반 대기열이나 줄처럼 작동합니다. 대기열의 끝에만 항목을 추가할 수 있으며 처음부터 가져올 수만 있습니다. 어느 시점에서 개발자는 양 끝에서 항목을 추가하고 가져오기 위해 향상된 버전의 대기열이 필요했습니다. 그래서 그들은 Deque양방향 대기열인 인터페이스를 만들었습니다. 일반 대기열의 모든 메서드가 있습니다. 결국 양방향 대기열의 부모이지만 새로운 메서드도 추가합니다.
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION