java8 interface의 public default, public static 메소드(default메소드와 접근제어자 혼동)

들어가기

아! 자과감 들고 괴로워... 이 글은 java8의 interface의 public default 메소드를 보며 햇갈렸던 내용을 정리한다.

Java8의 public default와 public static 메소드

Java8에서 확장성을 위해 Interface에 default, static 메소드라는 것을 추가했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
interface testInterface{

//상수
타입 상수명 = 값;
//추상메소드
타입 메소드명(매개변수,...);

//디폴트 메소드
default 타입 메소드명(매개변수,...){
...
}

//정적 메소드
static 타입 메소드명(매개변수,...){
....
}

}

디폴트 메소드는 인터페이스를 구현한 객체에서 호출할수 있으며, 정적메소드는 인터페이스명으로 접근하여 호출할수 있다. 직관 적이며 간단하다.

그런데 자바 책을 복습겸 책을 뒤적이다보니, 이런 설명을 보았다.

  • 인터페이스의 디폴트 메소드는 public 특성을 갖기 때문에 public을 생략하더라도 자동적으로 컴파일 과정에서 붙게 된다.
  • 인터페이스의 정적 메소드는 public 특성을 갖기 때문에 public을 생략하더라도 자동적으로 컴파일 과정에서 붙게 된다.

즉 컴파일 될때 아래처럼 public 접근제어자가 추가된다는 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interface testInterface{

...

//디폴트 메소드
[public] default 타입 메소드명(매개변수,...){
...
}

//정적 메소드
[public] static 타입 메소드명(매개변수,...){
....
}

}

원래 java의 interface의 메소드는 기본적으로 public 접근 제한을 갖고, 인터페이스를 구현하는 클래스는 public 보다 낮은 접근 제한으로 작성할수 없다. 따라서 당연한 소리일 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface TestIn {

public default String fn1() {
return "디폴트 메소드";
}

public static String fn2() {
return "정적 메소드";
}

public String fn3();

}

위처럼 직접 타이핑으로 public default 메소드를 인터페이스에 선언할 수도 있다.

여기가 내가 햇갈린 부분인데, java의 접근제어자 default와 java8의 interface내부에 선언된 default 메소드이다. 나는 위 코드를 보고, fn1메소드는 public 접근제어자와 default 접근제어자를 중복으로 갖는것인가? 라고 착각했다.

아이고 copy & paste만 하다보니, 확실히 감이 떨어졌다.

결론

  • interface에 선언된 default라는 키워드는 접근제어자가 아니고, default method를 선언하기 위한 키워드이다.

  • 그리고 default 접근제어자는 사실 default 키워드로 명시하지 않으며, 또한 어떠한 접근제어자 키워드도 사용하지 않는다.

default 접근제어 클래스

1
2
3
4
5
6
7
8
9
10
11
12
public class Test2 {

public String fn1() {
return "메소드";
}

}

//디폴트 클래스
class Test3{

}

클래스의 default 필드

1
2
3
4
5
6
7
8
9
10
11
12

//디폴트 클래스
class Test3{

//디폴트 접근제어 멤버변수
String name;

//디폴트 접근제어 메소드
void doSomething(){
}

}

마무리

아이고, 아는것보다 모르는게 점점 많아지는 것은 기분탓이겠지.