[강의] 인프런 : 더 자바, Java8 섹션 2

haeny-dev·2021년 7월 15일
post-thumbnail

📌 섹션 2 : 인터페이스의 변화

➕ 인터페이스 기본 메소드와 스태틱 메소드

1. 기본메소드(Default Methods)

  • 인터페이스에 메소드 선언이 아니라 구현체를 제공하는 방법

  • 해당 인터페이스를 구현한 클래스를 깨트리지 않고 새 기능을 추가할 수 있다.

  • 기본 메소드는 구현체가 모르게 추가된 기능으로 리스크가 있다.

    public interface Foo {
    
      void printName();
      String getName();
    
      /**
       * @implSpec
       * 이 구현체는 getName()으로 가져온 문자열을 대문자로 바꿔 출력한다.
       * getName()을 참조하므로, 해당 메소드에서 Null을 반환하는 경우 RuntimeException을 발생시킬 수 있습니다.
       */
      default void printNameUpperCase(){
          System.out.println(getName().toUpperCase());
      }
    }
  • Object가 제공하는 기능(equals, hasCode..)는 기본 메소드로 제공할 수 없고, 구현체가 재정의 해야한다.

  • 인터페이스를 상속받는 다른 인터페이스에서 기본 메소드를 그대로 제공하기 싫은 경우 다시 추상 메소드로 변경 할 수 있다.

  • 서로 다른 인터페이스에서 같은 이름의 기본 메소드를 가지고 있고, 그 서로 다른 인터페이스를 모두 구현하는 구현체의 경우
    충돌이 발생하므로, 기본 메소드를 직접 재정의 해주어야 한다.

    public class DefaultFoo implements Foo, Bar{
    
         String name;
    
         public DefaultFoo(String name) {
             this.name = name;
         }
    
         /*
         * Foo, Bar 인터페이스 모두 printNameUpperCase 디폴트 메소드를 가지고 있는 경우
         * 컴파일러는 어떤 메소드를 사용해야될지 판단할 수 없기 때문에, 직접 재정의해줘야 한다.
         * */
         @Override
         public void printNameUpperCase() {
             System.out.println("디폴트 메소드를 재정의한 메소드");
         }
    
         @Override
         public void printName() {
             System.out.println(this.name);
         }
    
         @Override
         public String getName() {
             return this.name;
         }
       }

2. 스태틱 메소드

public interface Foo {
  void printName();

  // 스태틱 메소드
  static void printAnything(){
      System.out.println("Foo");
  }
}

➕ 자바 8 API의 기본 메소드와 스태틱 메소드

인터페이스의 기본 메소드 추가에 따른 개발 방식의 변화

Java8 이전에는 인터페이스 내 하나의 메소드를 사용하기 위해서는 해당 인터페이스 안에 있는 메소드를 모두 구현해야 되는 번거로움이 있었습니다.

그래서 편의성을 위해서 해당 인터페이스를 구현한 추상클래스를 만들고, 그 추상클래스를 상속받아 필요한 메소드만 재정의 하여 사용하는 개발방식이 있었습니다.

하지만, Java8 에서 인터페이스의 기본 메소드가 추가되고 난 후에는 추상클래스를 생성하여 상속받는 형태의 개발을 하지 않아도 기본 메소드로 선언해주고, 상속이 아닌 구현체로서 필요한 메소드만 재정의하여 사용할 수 있게 되었습니다.

예를 들면, Java8 이전에는 WebMvcConfigurer 인터페이스를 구현한 추상클래스 WebMvcConfigurerAdapter를 상속받아 사용해왔지만,

Java8 이후에 해당 인터페이스 내의 메소드들이 기본 메소드로 선언이 되면서 WebMvcConfigurerAdapter 추상클래스를 상속받아 사용할 일이 없어져 해당 클래스는 Deprecated 되었습니다.

REFERENCE

➕ Default Methods
➕ Evolving Interfaces
➕ Iterable
➕ Spliterator
➕ Comparator

0개의 댓글