인터페이스는 일종의 추상클래스이다. 인터페이스는 추상클래스처럼 추상메소드를 갖지만
추상클래스보다 추상화 정도가 높아서 추상클래스와 달리 일반 메소드 또는 멤버변수를 구성원으로 가질 수 없다.
오직 추상메소드와 상수만을 멤버로 가질 수 있으며, 그 외의 다른 어떠한 요소도 허용하지 않는다. (JDK 1.8 이전)
개발 시간 단축
표준화 가능
서로 관계없는 클래스들 간의 관계를 맺어준다
독립적인 프로그래밍이 가능
인터페이스를 작성하는 것은 클래스를 작성하는 것과 같다. 키워드로 class 대신 interface를 사용한다.
interface에도 class와 같이 접근제어자로 public 또는 default를 사용할 수 있다.
ex)
interface 인터페이스 {
public static final 타입 상수이름 = 값;
public abstract 메소드이름(매개변수);
}
여기서 public static
, public abstract
은 생략 가능하다.
인터페이스에 메서드를 추가한다는 것은, 추상 메서드를 추가한다는 것이고, 이 인터페이스를 구현한 기존의 모든 클래스들이 새로 추가된 메서드를 구현해야 한다.
인터페이스가 변경되지 않으면 제일 좋지만, 언젠가는 변경이 발생하기 마련이다. 이를 해결하기 위해서 디폴트 메서드(default method)라는 것이 고안되었다. 디폴트 메서드는 추상 메서드의 기본적인 구현을 제공하는 메서드로, 추상 메서드가 아니기 때문에 디폴트 메서드가 새롭게 추가되어도 해당 인터페이스를 구현한 클래스를 변경하지 않아도 된다.
디폴트 메서드는 앞에 키워드 default를 붙이며, 추상 메서드와 달리 일반 메서드처럼 몸통 { }이 있어야 한다. 접근 제어자는 public이며, 생략이 가능하다.
ex)
interface MyInterface {
void method();
// void newMethod(); 추상 메서드
default void newMethod() { }
}
추상 메서드를 추가하는 대신 디폴트 메서드를 추가하면 조상 클래스에 새로운 메서드를 추가한 것과 동일한 효과를 얻는다.
새로 추가된 디폴트 메서드가 기존의 메서드와 이름이 중복되어 충돌하는 경우 해결하는 규칙은 다음과 같다.
단순하게 필요한 쪽의 메서드와 같은 내용으로 오버라이딩 해서 해결하는 방법도 있다.
Java 8부터 인터페이스에 static 메서드 추가가 가능해졌다. 클래스에서 작성하는 방법과 동일하게 작성할 수 있고, 접근 제어자는 항상 public이며 역시 생략이 가능하다.
static 메서드는 오버라이딩이 불가능하다.
Java 9부터 사용할 수 있게된 private 메서드는 다음과 같은 특성을 가지고 있다.
Constant Interface는 오직 상수만 정의한 인터페이스이다.
인터페이스에서 변수를 등록할 때 자동으로 public static final이 붙어서 상수처럼 어디에서나 접근할 수 있다.
또한 하나의 클래스에 여러 개의 인터페이스를 implement 할 수 있는데, Constant Interface를 implement 할 경우, 인터페이스의 클래스명을 네임스페이스로 붙이지 않고 바로 사용할 수 있다.
다만 Constant Interface는 사용을 추천하지 않는 Anti패턴이다.
사용하지 않을 수도 있는 상수를 포함하여 모두 가져오기 때문에 계속 가지고 있어야한다.
컴파일할 때 사용되겠지만, 런타임에는 사용할 용도가 없다.
Binary Code Compatibility (이진 호환성)을 필요로 하는 프로그램의 경우, 새로운 라이브러리를 연결하더라도 상수 인터페이스는 프로그램이 종료되기 전까지 이진 호환성을 보장하기 위해 계속 유지되어야 한다.
IDE가 없으면, 상수 인터페이스를 Implement한 클래스에서는 상수를 사용할 때 네임스페이스를 사용하지 않으므로, 해당 상수의 출처를 쉽게 알 수 없다. 또한 상수 인터페이스를 구현한 클래스의 하위 클래스들의 네임스페이스도 인터페이스의 상수들로 오염된다.
인터페이스를 구현해 클래스를 만든다는 것은, 해당 클래스의 객체로 어떤 일을 할 수 있는지 클라이언트에게 알리는 행위이다. 상수 인터페이스를 구현한다는 사실은 클라이언트에게는 중요한 정보가 아니다. 단지 클라이언트들을 혼란에 빠트릴 뿐이다.
상수 인터페이스를 Implement한 클래스에 같은 상수를 가질 경우, 클래스에 정의한 상수가 사용되므로 사용자가 의도한 흐름으로 프로그램이 돌아가지 않을 수 있다.
따라서 이에 대한 방안으로 이에 대한 방안으로 import static 구문의 사용을 권장한다.
참조