삽질저장소

자바 인터페이스

2021-01-09whiteship-live-study

whiteship/live-study 8주차 정리

  • 목표

  • 학습할 것 (필수)

    • 인터페이스 정의하는 방법
    • 인터페이스 구현하는 방법
    • 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법
    • 인터페이스 상속
    • 인터페이스의 기본 메소드 (Default Method), 자바 8
    • 인터페이스의 static 메소드, 자바 8
    • 인터페이스의 private 메소드, 자바 9

1. 인터페이스 정의하는 방법

  • 인터페이스의 모든 메소드는 추상적이다.
  • 인터페이스는 공용 API 를 정의하기 때문에 암시적으로 public 이므로 public 키워드는 생략하는 것이 일반적이다.
  • 인스턴스 필드를 정의할 수 없다.(필드는 구현의 세부사항이고 인터페이스는 구현이 아니라 사양이다.)
  • 인터페이스는 인스턴스화 할수 없으므로 생성자가 필요 없다.
  • 인터페이스는 중첩될 수 있다.
  • java 8부터 인터페이스에 static 메소드를 정의할 수 있다.
  • java 8부터 인터페이스에 default 메소드를 정의할 수 있다.
  • java 9부터 인터페이스에 private 메소드를 정의할 수 있다.
  • public interface Animal {
      String getName();
      int getLegs();
    }

2. 인터페이스 구현하는 방법

  • 상속에 extends 키워드를 사용했다면, 인터페이스는 implements 키워드를 사용한다.
  • 상속은 부모의 기능들을 재사용하는 개념이라면, 인터페이스는 공통의 기능들을 정의하고 이를 구현하는 클래스에서 해당 기능들을 필수적으로 Override 하여 구현해야 한다.
  • public class Cat implements Animal {
    
      @Override
      public String getName() {
          return "고양이";
      }
    
      @Override
      public int getLegs() {
          return 4;
      }
    }

3. 인터페이스 레퍼런스를 통해 구현체를 사용하는 방법

  • 인터페이스는 구현체를 통해서 인스턴스 생성이 가능하다.
  • 구현체를 통해 인스턴스를 생성할때 인터페이스 타입으로도 생성이 가능하다.
  • Cat cat = new Cat();
    Animal cat = new Cat();

4. 인터페이스 상속

  • 인터페이스는 다른 인터페이스를 상속(확장) 할 수 있으며, 클래스가 다른 클래스를 상속하는 것과 동일하게 extends 키워드를 사용하여 인터페이스를 상속할 수 있다.
  • 인터페이스는 클래스와 다르게 여러 인터페이스를 상속 할 수 있다.
  • 부모 인터페이스의 모든 메소드와 상수를 상속하고 새 메소드와 상수를 정의 할 수 있다.

    public interface PrintableAnimal extends Animal {
      void print();
    }
    
    // 구현 클래스
    public class Puppy implements PrintableAnimal {
    
      // Animal 인터페이스 메소드 구현
      @Override
      public String getName() {
          return "강아지";
      }
    
      // Animal 인터페이스 메소드 구현
      @Override
      public int getLegs() {
          return 4;
      }
    
      // PrintableAnimal 인터페이스 메소드 구현
      @Override
      public void print() {
          System.out.println("이름 : " + getName());
          System.out.println("다리개수 : " + getLegs());
      }
    
    }

5. 인터페이스의 기본 메소드 (Default Method), 자바8

  • default method 는 java8 부터 사용 가능하다.
  • 인터페이스가 default 키워드로 선언되면 메소드를 구현할 수 있고, 이를 구현하는 클래스는 default 메소드를 오버라이딩 할 수 있다.
  • implements 한 인터페이스의 default 메소드를 사용하려면 상속한인터페이스.super.메소드명 으로 사용할 수 있다.
  • public interface PrintableAnimal extends Animal {
    
    default void print() {
      System.out.println("이름 : " + getName());
      System.out.println("다리개수 : " + getLegs());
    }

6. 인터페이스의 static 메소드, 자바 8

  • static method 는 java8 부터 사용 가능하다.
  • static 메소드 이므로 상속이 불가능하다.
  • public interface PrintableAnimal extends Animal {
    
      static String getDescription() {
          return "출력기능이 있는 동물 인터페이스";
      }
    }
    
    // 사용
    System.out.println(PrintableAnimal.getDescription());

7. 인터페이스의 private 메소드, 자바 9

  • private method 는 java9 부터 사용 가능하다.
  • private 메소드 이기 때문에 인터페이스에서 구현이 되어 있어야 한다.
  • 구현체에서 구현할 수 없고, 자식 인터페이스에서도 상속이 불가능하다.
  • static 메소드도 private 로 쓸 수 있다.

8. Constant Interface

  • Constant Interface 는 오직 상수만 정의한 인터페이스로 사용을 추천하지 않는 Anti 패턴이다.
  • 인터페이스에서 변수를 등록할 때 자동으로 public static final 이 붙어서 상수처럼 어디에서나 접근할 수 있다. 또한 하나의 클래스에 여러 개의 인터페이스를 implement 할 수 있는데, Constant Interface 를 implement 할 경우, 인터페이스의 클래스명을 네임스페이스로 붙이지 않고 바로 사용할 수 있다.
  • 사용을 추천하지 않는 이유

    • 사용하지 않을 수도 있는 상수를 포함하여 모두 가져오기 때문에 불필요한 것들을 계속 가지고 있어야 한다.
    • 컴파일 할 때 사용되겠지만, 런타임에는 사용할 용도가 없다.
    • Binary Code Compatibility (이진 호환성)을 필요로 하는 프로그램의 경우, 새로운 라이브러리를 연결하더라도 상수 인터페이스는 프로그램이 종료되기 전까지 이진 호환성을 보장하기 위해 계속 유지되어야 한다.
    • IDE 가 없으면, 상수 인터페이스를 Implement 한 클래스에서는 상수를 사용할 때 네임스페이스를 사용하지 않으므로, 해당 상수의 출처를 쉽게 알 수 없다. 또한 상수 인터페이스를 구현한 클래스의 하위 클래스들의 네임스페이스도 인터페이스의 상수들로 오염된다.
    • 인터페이스를 구현해 클래스를 만든다는 것은, 해당 클래스의 객체로 어떤 일을 할 수 있는지 클라이언트에게 알리는 행위이다. 상수 인터페이스를 구현한다는 사실은 클라이언트에게는 중요한 정보가 아니다. 단지 클라이언트들을 혼란에 빠트릴 뿐이다.
    • 상수 인터페이스를 Implement 한 클래스에 같은 상수를 가질 경우, 클래스에 정의한 상수가 사용되므로 사용자가 의도한 흐름으로 프로그램이 돌아가지 않을 수 있다.

9. 인터페이스 vs 추상클래스

  • java8 부터 default method, static method 가 사용가능하게 되었고, java9 부터는 private method 도 인터페이스가 사용가능하게 되었다. 그렇다면 인터페이스와 추상클래스가 큰 차이가 없어 보이는데 어떤 것을 사용해야 할까?

    • 추상 클래스에서는 private 변수를 선언하고 상태 정보를 가질 수 있다. 즉 어떠한 상태 정보 같은 것이 필요할 경우에는 추상 클래스를 사용한다.
  • 느슨한 결합을 유지하게 위해 인터페이스를 구현한 클래스를 사용할때에는 인터페이스 타입을 사용해야 한다.

참조링크

  • Thank You for Visiting My Blog, Have a Good Day 😆
    © 2021 Developer shPark, Powered By Gatsby.