JavaRush /Java Blog /Random-KO /Java의 인터페이스

Java의 인터페이스

Random-KO 그룹에 게시되었습니다
안녕하세요! 오늘 우리는 Java의 중요한 개념인 인터페이스에 대해 이야기하겠습니다. 그 단어는 아마도 당신에게 친숙할 것입니다. 예를 들어, 대부분의 컴퓨터 프로그램과 게임에는 인터페이스가 있습니다. 넓은 의미에서 인터페이스는 상호 작용하는 두 당사자를 연결하는 일종의 "원격 제어"입니다. 일상생활에서 사용되는 인터페이스의 간단한 예는 TV 리모컨입니다. 사람과 TV라는 두 개체를 연결하고 볼륨을 높이거나 낮추고, 채널을 변경하고, TV를 켜거나 끄는 등 다양한 작업을 수행합니다. 한 쪽(사람)이 작업을 수행하려면 다른 쪽이 인터페이스에 액세스해야 합니다(리모컨 버튼 누르기). 예를 들어 TV에서 채널을 다음 채널로 전환하는 경우입니다. 이 경우 사용자는 TV 장치와 채널 변경 프로세스가 TV 내부에서 어떻게 구현되는지 알 필요가 없습니다. Java에서 인터페이스가 필요한 이유 - 1사용자가 액세스할 수 있는 모든 것은 인터페이스 뿐입니다 . 주요 임무는 원하는 결과를 얻는 것입니다. 이것이 프로그래밍과 Java와 어떤 관련이 있습니까? 직접 :) 인터페이스를 생성하는 것은 일반 클래스를 생성하는 것과 매우 유사하지만 단어 대신에 class단어를 지정한다는 점만 다릅니다 interface. 가장 간단한 Java 인터페이스를 살펴보고 이것이 어떻게 작동하고 무엇이 필요한지 알아 보겠습니다.
public interface Swimmable  {

     public void swim();
}
우리는 수영할 수 있는Swimmable 인터페이스 를 만들었습니다 . 이것은 하나의 "버튼"이 있는 리모콘과 비슷합니다. 방법은 "수영"입니다. 이 " 리모컨 "을 어떻게 사용할 수 있나요 ? 이를 위해 방법은 다음과 같습니다. 리모컨의 버튼을 구현해야 합니다. 인터페이스를 사용하려면 프로그램의 일부 클래스에서 해당 메서드를 구현해야 합니다. "수영할 수 있다"라는 설명에 맞는 객체를 가진 클래스를 생각해 봅시다. 예를 들어 duck 클래스가 적합합니다 . swim()Duck
public class Duck implements Swimmable {

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

    public static void main(String[] args) {

        Duck duck = new Duck();
        duck.swim();
    }
}
여기서 무엇을 볼 수 있나요? 클래스는 키워드를 사용하여 Duck인터페이스와 연결됩니다 . 기억하신다면, 상속에서 두 클래스를 연결하기 위해 비슷한 메커니즘을 사용했는데, " extends " 라는 단어만 있었습니다 . " "는 명확성을 위해 문자 그대로 번역될 수 있습니다. "공용 클래스는 인터페이스를 구현합니다 ." 이는 인터페이스와 연관된 클래스가 모든 메소드를 구현해야 함을 의미합니다. 참고: 우리 클래스에는 인터페이스와 마찬가지로 메소드가 있고 그 내부에는 일종의 로직이 있습니다. 이는 필수 요구 사항입니다. 방금 " "라고 쓰고 클래스에 메소드를 생성하지 않은 경우 컴파일러는 다음과 같은 오류를 표시합니다. Duck은 추상이 아니며 Swimmable에서 추상 메소드 swim()을 재정의하지 않습니다. 왜 이런 일이 발생합니까? TV를 예로 들어 오류를 설명하면 채널 변경 방법을 모르는 TV에서 '채널 변경' 버튼이 있는 리모컨을 사람에게 주는 것으로 나타났습니다. 이 시점에서 버튼을 원하는 만큼 눌러도 아무것도 작동하지 않습니다. 리모콘 자체는 ​​채널을 변경하지 않습니다. TV에 신호만 제공하며 내부에는 채널 변경의 복잡한 프로세스가 구현됩니다. 우리 오리도 마찬가지입니다. 인터페이스를 사용하여 접근할 수 있으려면 오리가 수영할 수 있어야 합니다 . 그녀가 이 작업을 수행하는 방법을 모른다면 인터페이스는 사람과 프로그램이라는 양측을 연결하지 않습니다. 사람은 프로그램 내부의 객체를 부유하게 만드는 방법을 사용할 수 없습니다 . 이제 인터페이스의 용도가 무엇인지 더 명확하게 살펴보았습니다. 인터페이스는 해당 인터페이스를 구현하는 클래스가 가져야 하는 동작을 설명합니다. "Behavior"는 메소드의 모음입니다. 여러 메신저를 만들고 싶다면 인터페이스를 만드는 것이 가장 쉬운 방법입니다 . 메신저는 무엇을 할 수 있어야합니까? 단순화된 형태로 메시지를 받고 보냅니다. Swimmableimplementspublic class Duck implements SwimmableDuckSwimmableDuckSwimmableswim()public class Duck implements Swimmableswim()DuckSwimmableSwimmableswim()DuckMessenger
public interface Messenger{

     public void sendMessage();

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

    public void sendMessage() {

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

     public void getMessage() {
         System.out.println("Reading the message in Telegram!");
     }
}
왓츠앱:
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 message to Viber!");
    }

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

    private WhatsApp whatsApp;
    private Telegram telegram;
    private Viber viber;
}
우리는 세 개의 필드를 만들었지만 클라이언트는 메신저를 하나만 가질 수 있습니다. 우리는 어느 쪽인지 모릅니다. 그리고 클라이언트와의 의사소통 없이 방치되지 않으려면 가능한 모든 옵션을 클래스에 "푸시"해야 합니다. 그 중 한두 개는 항상 존재하며 null프로그램이 작동하는 데 전혀 필요하지 않은 것으로 나타났습니다. 대신 다음 인터페이스를 사용하는 것이 더 좋습니다.
public class Client {

    private Messenger messenger;
}
이것은 "느슨한 결합"의 예입니다! 클래스에 특정 메신저 클래스를 지정하는 대신 Client클라이언트에 메신저가 있다는 점만 언급합니다. 어느 것이 프로그램 진행 중에 결정될 것입니까? 그런데 왜 인터페이스가 필요한가요? 왜 언어에 추가 되었습니까? 질문이 좋고 정확합니다! 일반적인 상속을 사용해도 동일한 결과를 얻을 수 있습니다. 그렇죠? 클래스 Messenger는 상위 클래스이고, 및 ViberTelegram상속자 WhatsApp입니다. 실제로 그렇게 하는 것이 가능합니다. 하지만 한 가지 문제가 있습니다. 이미 알고 있듯이 Java에는 다중 상속이 없습니다. 그러나 인터페이스에는 여러 가지 구현이 있습니다. 클래스는 원하는 만큼 많은 인터페이스를 구현할 수 있습니다. Smartphone필드 Application(스마트폰에 설치된 애플리케이션)가 있는 클래스가 있다고 상상해 보세요 .
public class Smartphone {

    private Application application;
}
물론 애플리케이션과 메신저는 비슷하지만 여전히 다릅니다. 메신저는 모바일과 데스크톱 모두일 수 있지만 애플리케이션은 모바일 애플리케이션입니다. Telegram따라서 상속을 사용하면 클래스에 객체를 추가할 수 없습니다 Smartphone. 결국, 클래스는 ! 로부터 Telegram상속받을 수 없습니다. 그리고 우리는 이미 그것을 에서 상속받아 이 형식으로 클래스에 추가했습니다 . 그러나 클래스는 두 인터페이스를 쉽게 구현할 수 있습니다! 따라서 클래스에서는 객체를 으로 구현할 수 있고 클래스에서는 으로 구현할 수 있습니다 . 수행 방법은 다음과 같습니다. ApplicationMessengerMessengerClientTelegramClientTelegramMessengerSmartphoneApplication
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이제 우리는 원하는 대로 클래스를 사용할 수 있습니다 . 어딘가에서 그는 의 역할로 Application, 어딘가에서 의 역할로 행동할 것입니다 Messenger. 아마도 인터페이스의 메소드가 항상 "비어 있다"는 것, 즉 구현이 없다는 것을 이미 알아차렸을 것입니다. 그 이유는 간단합니다. 인터페이스는 동작을 설명하는 것이지 구현하는 것이 아닙니다. “인터페이스를 구현하는 클래스의 모든 객체는 Swimmable부동할 수 있어야 합니다.” 이것이 인터페이스가 우리에게 말하는 전부입니다. 물고기, 오리 또는 말이 정확히 어떻게 헤엄칠지는 인터페이스가 아닌 클래스 및 에 대한 Fish질문 Duck입니다 . Horse채널을 바꾸는 것이 TV의 임무와 마찬가지로. 리모콘은 간단히 버튼만 제공합니다. 그러나 Java8에는 기본 메소드라는 흥미로운 추가 기능이 있습니다. 예를 들어 인터페이스에는 10개의 메서드가 있습니다. 그 중 9개는 클래스마다 다르게 구현되지만, 하나는 모두 동일하게 구현됩니다. 이전에는 Java8이 출시되기 전에는 인터페이스 내부의 메소드에 전혀 구현이 없었습니다. 즉, 컴파일러에서 즉시 오류가 발생했습니다. 이제 다음과 같이 할 수 있습니다:
public interface Swimmable {

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

   public void eat();

   public void run();
}
키워드를 사용하여 default기본 구현으로 인터페이스에 메서드를 만들었습니다. 를 구현할 모든 클래스에서 다른 두 메서드 eat()및 를 구현해야 합니다 . 메서드를 사용하여 이 작업을 수행할 필요는 없습니다 . 구현은 모든 클래스에서 동일합니다. 그건 그렇고, 당신은 이전 작업에서 인터페이스를 두 번 이상 접했지만 스스로 알아차리지는 못했습니다. :) 다음은 분명한 예입니다. 인터페이스 및 ! 보다 정확하게는 , 및 기타 구현을 사용합니다 . 동일한 다이어그램은 하나의 클래스가 여러 인터페이스를 동시에 구현하는 경우의 예를 보여줍니다. 예를 들어 인터페이스 및 (양면 대기열)을 구현합니다. 또한 인터페이스 또는 그 구현에 대해서도 잘 알고 있습니다 . 그런데 이 다이어그램에서는 인터페이스가 서로 상속될 수 있다는 한 가지 기능을 볼 수 있습니다. 인터페이스는 에서 상속되고 , queue 에서 상속됩니다 . 이는 인터페이스 간의 연결을 표시하려고 하는데 한 인터페이스가 다른 인터페이스의 확장 버전인 경우에 필요합니다. 인터페이스 (큐) 를 사용한 예를 살펴보겠습니다 . 아직 컬렉션을 살펴보지는 않았지만 매우 단순하고 매장의 일반 줄처럼 배열되어 있습니다. 대기열의 끝에만 요소를 추가할 수 있고 처음부터 요소를 제거할 수 있습니다. 특정 단계에서 개발자는 양쪽에서 요소를 추가하고 수신할 수 있도록 확장된 버전의 대기열이 필요했습니다. 이것이 양방향 대기열이라는 인터페이스가 생성된 방법입니다 . 양방향 대기열의 "상위"이기 때문에 일반 대기열의 모든 메소드를 포함하지만 새로운 메소드가 추가되었습니다. run()Swimmableswim()Java에서 인터페이스가 필요한 이유 - 2ListSetArrayListLinkedListHashSetLinkedListListDequeMapHashMapSortedMapMapDequeQueueQueueQueueDeque
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION