기록/JAVA

[JAVA8] 인터페이스 기본 메서드와 스태틱 메서드

jeongdalma 2021. 1. 10. 15:01

기본 메서드 (Default Methods)

  • 인터페이스에 메서드 선언이 아니라 구현체를 제공하는 방법
  • 해당 인터페이스를 구현한 클래스를 깨뜨리지 않고 새 기능을 추가할 수 있다.
  • 기본 메서드는 구현체가 모르게 추가된 기능으로 그만큼 리스크가 있다.
    • 컴파일 에러는 아니지만 구현체에 따라 런타임 에러가 발생할 수 있다.
    • 반드시 문서화 할 것(@implSpec 자바독 태그 사용 , 자바8에서 추가되었음)
  • Object 제공하는 기능 (equals , hashCode , toString 등등..)은 기본 메서드로 제공 할 수 없다.
    • 구현체를 재정의 해야 한다.
  • 본인이 수정할 수 있는 인터페이스 에만 기본 메서드를 제공할 수 있다.
  • 인터페이스를 상속받는 인터페이스에서 다시 추상 메서드로 변경할 수 있다.
  • 인터페이스 구현체가 재정의 할 수도 있다.
public interface InterfaceTest {
    void printName();
    String getName();
//    void printNameUpperCase();

    /**
     * @implSpec 이 구현체는 getName()으로 가져온 문자열을 대문자로 바꿔 출력한다.
     */
    default void printNameUpperCase(){
        System.out.println("print name Upper case : " + getName().toUpperCase());
    }

//    void printNameUpperCase(); 를 추상메서드로 추가하게 되면 
//    이 인터페이스를 구현하고있는 구현체를 다 수정하여야 하는 번거로움이 생긴다.
    
//    인터페이스에 메서드를 default를 선언하고 로직(바디)을 작성해 놓으면 
//    이 인터페이스를 구현하는 구현체는 default 메서드를 쓸 수 있다.
}
public interface InterfaceTest2 extends InterfaceTest{

    // 추상 메서드를 재정의 하지 않으면 InterfaceTest에서 제공하는
    // printNameUpperCase 구현체가 제공된다.
    // 만약, 재정의 하지 않고 InterfaceTest2를 구현하게 되어도
    // 그 구현체는 InterfaceTest의 printNameUpperCase의 메서드를 사용할 수 있다.
    void printNameUpperCase();
}
public class AppForInterfaceTest implements InterfaceTest{
    String name;

    public AppForInterfaceTest(String name) {
        this.name = name;
    }

    @Override
    public void printName() {
        System.out.println("print name : " + this.name);
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public void printNameUpperCase() {
        System.out.println("(Override)print name Upper case : " + getName().toUpperCase());
    }

    public static void main(String[] args) {
        AppForInterfaceTest test = new AppForInterfaceTest("Today 2021-01-10");
        test.printName();
        test.printNameUpperCase();

//        출력
//        print name : Today 2021-01-10
//        print name Upper case : TODAY 2021-01-10
//        (Override)print name Upper case : TODAY 2021-01-10
    }
}

만약 InterfaceTest와 InterfaceTest2(extends InterfaceTest걷어낸 후)에서

동일한 default printNameUpperCase를 구현하면 ??

AppForInterfaceTest는 2개의 인터페이스를 구현하는데 ,2개 중에 무슨 printNameUpperCase를 써야하는지 모르기 때문에 컴파일 에러가 발생한다.

 

 

스태틱 메서드 (Static Methods)

  • 해당 타입 관련 헬퍼 또는 유틸리티 메서드를 제공할 때 인터페이스 스태틱 메서드를 제공할 수 있다.
public interface InterfaceTest {
    void printName();
    String getName();

    /**
     * @implSpec 이 구현체는 getName()으로 가져온 문자열을 대문자로 바꿔 출력한다.
     */
    default void printNameUpperCase(){
        System.out.println("print name Upper case : " + getName().toUpperCase());
    }

    static void printAnything(){
        System.out.println("Interface Test");
    }
    
}
public class AppForInterfaceTest implements InterfaceTest{
    String name;

    public AppForInterfaceTest(String name) {
        this.name = name;
    }

    @Override
    public void printName() {
        System.out.println("print name : " + this.name);
    }

    @Override
    public String getName() {
        return this.name;
    }

    public static void main(String[] args) {
        InterfaceTest.printAnything();
        
        // 출력
        // Interface Test
    }
}

 

 

 

 

 

 

더 자바, Java 8 - 인프런

자바 8에 추가된 기능들은 자바가 제공하는 API는 물론이고 스프링 같은 제 3의 라이브러리 및 프레임워크에서도 널리 사용되고 있습니다. 이 시대의 자바 개발자라면 반드시 알아야 합니다. 이

www.inflearn.com