본문 바로가기
  • 시 쓰는 개발자
1일 1개념정리 (24년 8월~)/Java

1일1개 (5) - 인터페이스

by poetDeveloper 2024. 8. 13.

1일 1개념정리 24.08.09.금 ~ 

 

큰 결정에 큰 동기가 따르지 않을 때도 있다. 하지만 큰 결심이 따라야 이뤄낼 수 있다.

무조건 무조건 1일 1개의 개념 정리하기 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!


#5. 인터페이스란 ?

자바에서 말하는 인터페이스는 뒤에서 이야기하도록 하고, 조금 더 넓은 인터페이스 개념에 대해 먼저 알아보자. 인터페이스는 일종의 매개체, 중간다리 역할을 한다. 한마디로 "소통을 가능하게 하는 연결 고리"라고 생각하면 편하다. 아래 예시를 보자.

 

일반적인 인터페이스

일반적으로는 두 시스템 사이에서 상호작용을 돕는 중간다리 정도로 이해한다. 예를 들면, 키보드, 마우스 등도 인터페이스를 사용하고 있는 것이다. 인간이 쓰는 입력을 컴퓨터가 이해하는 형태로 전달하고, 반대로도 컴퓨터의 출력을 다시 인간이 이해할 수 있게 변환해주는 이런 역할을 인터페이스가 하게 된다.

기술적인 인터페이스

그럼 좀 더 기술적으로 이야기하는 인터페이스는 무엇인가 ?

  • UI : 사용자 - 시스템 사이의 인터페이스이다. 화면을 터치하면 그 터치로 인해 어떤 기능이 실행되는 이것을 말한다.
  • API : 두개의 프로그램 사이에서 연결을 주고받을 수 있게 도와주는 인터페이스이다. 예를들면, 어떤 사이트에 로그인할 때 네이버로그인 / 카카오로그인 이런 것들이 있지 않는가 ? 해당 사이트에서 네이버로/카카오로 로그인 정보를 달라고 요청을 날리고 가운데서 누군가가 이 정보들을 처리하고 있을 것이다.

하드웨어 인터페이스

그럼 하드웨어에서 말하는 인터페이스는 무엇이겠는가? 하드웨어끼리 연결할 때 소통이 가능하도록 이어주는 연결장치이다. 가장 대표적으로 USB이다. 저장장치 USB 뿐만 아니라, 요즘은 USB 선풍기, USB 무드등처럼 여러 제품들을 본적이 있을 것이다. 생각해보면 USB 인터페이스만 똑같지, 저장장치, 선풍기, 무드등 이런것들은 제각기 다른 제품들이다. 이렇게 포트만 맞춰놓으면 여러 기능을 사용할 수 있게 된다.

 

 

인터페이스 왜 쓸까 ??   

1) 표준화, 일관성

일단 생각해보자. A와 B가 데이터를 주고받는데, 인터페이스가 없다면 A는 B에게 적합한 형태로 데이터를 보내야한다. 근데 C, D, E ... 모두에게 적합하게 만들면 A는 과로로 쓰러질 것이다. 근데 만약 "데이터를 이동시켜주는 누군가"가 있다면 ?? 모든 사람들이 이 사람에게 데이터를 전달하면 끝이니까, 이사람에게만 적합하도록 데이터를 보내면 된다.

A -> I -> B

B -> I -> A

C -> I -> Z

O -> I -> Q 등등

따라서, 인터페이스를 통해 "표준화"를 할 수 있다.

2) 재사용성

1번처럼 I라는 인터페이스를 만들어놓으면 나중에 만약 P랑 Q이 소통할 때에도 I를 가져다 쓰면 되지 않겠는가 ? 재사용성이 좋고 이는 개발 효율에도 영향을 미친다.

3) 유연한 설계

인터페이스를 사용하면 클래스 간의 의존성을 줄일 수 있어 더 유연하게 설계할 수 있다. A와 B가 직접 통신하면, A는 B의 내부 구조나 데이터를 처리하는 방법을 알아야 한다. 이는 A와 B가 강하게 결합된 상태로 만들어, B가 변경될 때마다 A도 변경해야 하는 상황이 발생한다. 그러나 인터페이스를 사용하면 A는 B가 무엇을 하는지만 알면 되고, 어떻게 하는지는 알 필요가 없다. 따라서 만약 B가 변경되더라도 A는 영향을 받지 않게 된다.

4) 다형성 지원

USB 포트같은 맥락이다. USB 포트부분만 인터페이스로 통하면 그 뒤는 선풍기든, 저장장치이든 뭘 만들든 그건 자기 몫이다.

5) 유지보수

당연히 인터페이스로 공통된 표준을 만들어놨으니, 유지보수에도 용이하다. 내 코드만 신경쓰면 되고, 시스템의 한 부분을 변경하더라도 다른 부분에 영향을 최소화할 수 있다.

6) 다중 상속 문제 해결

인터페이스는 여러 개를 구현할 수 있기 때문에, 다중 상속이 필요한 상황에서도 충돌 없이 다양한 기능을 클래스에 부여할 수 있다.

7) DIP 준수 (의존성 역전 원칙)   

  • 고수준 모듈 : A = 애플리케이션 핵심 로직 담당
  • 저수준 모듈 : B = 이를 지원하는 구체적인 기능을 제공

이렇다고 할때 DIP는 A가 B에 의존하지 않고, 둘 다 추상적인 인터페이스(I)에 의존하도록 하여, B가 변경되더라도 A에 영향을 주지 않게 하는 원칙이다. 이를 통해 시스템의 유연성과 유지보수성이 크게 향상된다.

 

Java에서 말하는 인터페이스

앞에선 인터페이스에 대한 개념을 말했다. Java에서는 이를 어떻게 쓰고 있을까 ???

 

Java에서 인터페이스는 클래스가 구현해야 하는 메소드의 집합이다. 인터페이스는 클래스가 어떤 메소드들을 반드시 구현해야 하는지 규정하는 역할을 한다. 주요 특징을 알아보자.

  1. 인터페이스는 메소드를 선언하기만 함 : 인터페이스는 메소드의 이름, 매개변수, 반환 타입만 정의하고, 메소드의 구현 내용은 포함하지 않는다. 구현은 인터페이스를 구현하는 클래스가 담당한다.
  2. 인터페이스는 다중 구현이 가능함 : 클래스는 하나의 부모 클래스만 상속받지만 인터페이스는 여러개를 구현할 수 있다. 이를 통해 다양한 기능을 클래스로 추가할 수 있다.
  3. 상수 필드만 포함 : 인터페이스 안에 선언된 필드는 자동으로 public static final로 간주되어서 상수로 사용된다.
  4. 디폴트 메소드와 정적 메소드 : Java 8부터 인터페이스는 default 키워드로 기본 메소드 를 사용해 기본 메소드 구현을 제공할 수 있게 되었고, static 메소드도 포함할 수 있게 되었다. default 메소드는 인터페이스를 구현하는 클래스에서 선택적으로 오버라이드할 수 있다.
  5. 추상 메소드 : 인터페이스 내의 메소드는 기본적으로 public이고 abstract이다. 따라서 구현 클래스는 이 메소드들을 반드시 구현해야 한다.
interface Animal {
    // 추상 메소드
    void sound();
    
    // 디폴트 메소드
    default void eat() {
        System.out.println("음식 먹는중");
    }

    // 정적 메소드
    static void sleep() {
        System.out.println("잠 자는중");
    }
}

// 클래스가 인터페이스를 구현
class Dog implements Animal {
    @Override
    public void sound() {
        System.out.println("으르릉");
    }
}

class Cat implements Animal {
    @Override
    public void sound() {
        System.out.println("애옹");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.sound(); // "으르릉"
        dog.eat();   // "음식 먹는중"
        
        Cat cat = new Cat();
        cat.sound(); // "애옹"
        cat.eat();   // "음식 먹는중"

        // 정적 메소드는 인터페이스 이름으로 호출
        Animal.sleep(); // "잠 자는중"
    }
}

 

'1일 1개념정리 (24년 8월~) > Java' 카테고리의 다른 글

1일1개 (19) - static  (0) 2024.08.28
1일1개 (18) - 상속과 구현  (0) 2024.08.27
1일1개 (17) - 오버라이딩 vs 오버로딩  (0) 2024.08.26
1일1개 (16) - 자바 final  (0) 2024.08.25
1일1개 (4) - JVM  (2) 2024.08.12