자바 8 인 터 페 이 스 를 아 는 기본 적 인 방법

머리말
자바 8 은 Oracle 이 2014 년 3 월 발표 한 중요 한 버 전 으로 API 는 기 존의 인터페이스 에 매우 많은 새로운 방법 을 도입 했다.
예 를 들 어 자바 8 의 List 인터페이스 에 sort 방법 이 추가 되 었 습 니 다.자바 8 이전에 List 인 터 페 이 스 를 실현 하 는 모든 클래스 는 sort 방법의 실현 을 정의 하거나 부모 클래스 에서 이 를 계승 해 야 합 니 다.만약 List 인터페이스의 계승 체계 가 매우 복잡 하 다 면 전체 집합 프레임 워 크 의 유 지 량 이 얼마나 되 는 지 상상 해 보 세 요!
이 를 위해 자바 8 에 새로운 메커니즘 을 도입 했다.인 터 페 이 스 는 설명 대 를 실현 하 는 방법 을 지원 한다.
기본 방법
앞에서 언급 한 자바 8 에서 List 인터페이스 에 sort 방법 이 추가 되 었 는데 그 소스 코드 는 다음 과 같다.

public interface List<E> extends Collection<E> {
 
 // ...    
  
 default void sort(Comparator<? super E> c) {
  ...
  ...
 }
}
이 새로 추 가 된 sort 방법 은 방법 체 가 있 고 default 수정자 로 장식 되 어 있 습 니 다.이것 이 바로 인터페이스의 기본 방법 입 니 다.
기본 방법 은 static 이 아 닌 것 이 분명 하기 때문에 인터페이스의 실현 클래스 의 인 스 턴 스 로 기본 방법 을 사용 해 야 합 니 다.
기본 적 인 방법 을 사용 하 는 인 터 페 이 스 를 사용자 정의 합 니 다.

public interface Sized {
 //       ,   public abstract   ,     
 int size();

 /*
  *     ,    
  *        Sized          isEmpty   
  */
 default boolean isEmpty() {
  return this.size() == 0;
 }
}
사실 JDK 버 전이 계속 업그레이드 되면 서 API 가 계속 발전 하고 있 습 니 다.기본 적 인 방법 은 자바 8 의 API 에서 대량으로 사용 되 었 습 니 다.위의 List 인터페이스 에서 sort 방법 은 바로 그 중의 하나 입 니 다.
추상 류 와 의 차이
어떤 학생 들 은 자바 8 에 기본 적 인 방법의 인 터 페 이 스 를 넣 었 다 는 것 을 발 견 했 을 것 이다.이것 이 바로 예전 의 추상 류 가 아 닙 니까?사실 둘 은 차이 가 있다.
4.567917.한 가지 유형 은 하나의 추상 류 만 계승 할 수 있다.하지만 한 종 류 는 여러 개의 인 터 페 이 스 를 실현 할 수 있다4.567917.추상 류 는 인 스 턴 스 변수 가 있 고 인 터 페 이 스 는 클래스 변수 만 있 을 수 있 습 니 다.4.567918.
충돌 을 해결 하 다
우 리 는 자바 언어 중의 한 종 류 는 하나의 부모 클래스 만 계승 할 수 있다 는 것 을 알 고 있 지만,한 종 류 는 여러 개의 인 터 페 이 스 를 실현 할 수 있다.기본 방법 이 자바 8 에 도입 되면 서 여러 서명 을 계승 하 는 방법 이 나 올 수 있 습 니 다.이런 상황 에서 클래스 는 어떤 함 수 를 사용 할 것 인가?
이러한 다 중 상속 관 계 를 해결 하기 위해 자바 8 은 다음 과 같은 세 가지 규칙 을 제공 합 니 다.
4.567917.클래스 의 방법 우선 순위 가 가장 높 고 클래스 나 부모 클래스 에서 설명 하 는 방법의 우선 순 위 는 모든 성명 이 기본 적 인 방법의 우선 순위 보다 높다4.567917.만약 에 첫 번 째 로 판단 할 수 없다 면 서브 인터페이스의 우선 순위 가 더욱 높다.방법 서명 과 동시에 가장 구체 적 으로 실현 되 는 기본 적 인 방법 을 가 진 인 터 페 이 스 를 우선 선택한다.즉,B 가 A 를 계승 하면 B 는 A 보다 더욱 구체 적 이다4.567917.마지막 으로 판단 할 수 없다 면 여러 개의 인 터 페 이 스 를 계승 한 종 류 는 반드시 명시 적 커버 와 기대 하 는 방법 을 통 해 어떤 기본 적 인 방법 을 사용 하 는 지 명시 적 으로 선택해 야 한다우리 함께 몇 가지 예 를 봅 시다.
필드 1:

public interface A {
 default void hello() {
  System.out.println("hello from A");
 }
}

public interface B extends A {
 default void hello() {
  System.out.println("hello from B");
 }
}

public class C implements A, B {
 public static void main(String[] args) {
  new C().hello();
 }
}

그림 1 과 같이 이 장면 의 UML 그림 입 니 다.
우 리 는 위의 세 가지 규칙 을 대조 해 보면,클래스 C 에서 main()방법 은 무엇 을 출력 합 니까?
4.567917.규칙(1)이 만족 하지 않 습 니 다
  • B 가 A 를 물 려 받 았 기 때문에 B 가 A 보다 더 구체 적 이기 때문에 B 의 hello()방법 을 선택해 야 한다.그래서 프로그램 은"hello from B"를 출력 합 니 다
  • 필드 2:
    C 가 아래 처럼 D 를 물 려 받 았 다 면 어떻게 되 었 을 까?
    
    public class D implements A {
    
    }
    
    public class C extends D implements A, B {
     public static void main(String[] args) {
      new C().hello();
     }
    }

    그림 2 와 같이 이 장면 의 UML 그림 입 니 다.
    마찬가지 로 우 리 는 세 가지 규칙 을 대조 해 보 았 다.
  • C 는 D 를 계 승 했 지만 D 에서 A 를 덮어 쓰 지 않 는 기본 방법 입 니 다
  • 이 어 컴 파일 러 는 A 와 B 중에서 선택 할 것 이다.B 가 더욱 구체 적 이기 때문에 프로그램 은'hello from B'를 출력 할 것 이다
  • 필드 3:
    위의 D 를 약간 수정 합 니 다:
    
    public class D implements A {
     public void hello() {
      System.out.println("hello from D");
     }
    }
    결 과 는 어 떻 습 니까?
    규칙(1)에 따라 부모 클래스 에서 설명 하 는 방법 이 더 높 은 우선 순 위 를 가지 기 때문에 프로그램 은'hello from D'를 출력 합 니 다.
    필드 4:
    지금 B 가 A 를 계승 하지 않 는 다 고 가정 하면:
    
    public interface A {
      default void hello() {
        System.out.println("hello from A");
      }
    }
    
    public interface B {
      default void hello() {
        System.out.println("hello from B");
      }
    }
    
    public class C implements A, B {
      public static void main(String[] args) {
        new C().hello();
      }
    }

    그림 3 과 같이 이 장면 의 UML 그림 입 니 다.
    이때 컴 파일 러 가 A 인지 B 인지 식별 할 수 없 기 때문에 컴 파일 오 류 를 던 집 니 다."C inherits unrelated defaults for hello()from types A and B".
    이러한 장면 에서 충돌 을 해결 하려 면 C 에서 hello()방법 을 덮어 쓰 고 방법 에 표 시 된 A 또는 B 를 호출 하 는 방법 을 선택 할 수 있 습 니 다.
    호출 방식 은 다음 과 같 습 니 다.
    
    public class C extends D implements A, B {
      public void hello() {
        //          B    
        //   ,     A    ,    :A.super.hello()
        B.super.hello();
      }
    
      public static void main(String[] args) {
        //    hello from B
        new C().hello();
      }
    }
    필드 5:
    
    public interface A {
      default void hello() {
        System.out.println("hello from A");
      }
    }
    
    public interface B extends A{
    
    }
    
    public interface C extends A{
    
    }
    
    public class D implements B, C {
      public void hello() {
        new D().hello();
      }
    }
    

    이 때 는 선택 할 수 있 는 방법 이 하나 밖 에 없 기 때문에 프로그램 은'hello from A'를 출력 합 니 다.
    총결산
    이상 은 이 글 의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가 치 를 가지 기 를 바 랍 니 다.여러분 의 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기