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

haeny-dev·2021년 7월 15일
0
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개의 댓글