자바의 정석 7장 (7) 인터페이스(interface)
7. 인터페이스(interface)
7-1 인터페이스란?
인터페이스는 일종의 추상클레스이다. 추상클래스처럼 추상메서드를 갖지만 추상클래스보다 추상화 정도가 높아서 몸통을 갖춘 일반메서드 또는 멤버변수를 구성원으로 가질 수 없다. 오직 추상메서드와 상수만을 멤버로 가질 수 있으며, 그 외의 다른 어떠한 요소도 허용하지 않는다.
추상클래스 - 미완성 설계도
인터페이스 - 기본 설계도
7-2 인터페이스의 작성
인터페이스를 작성하는 것은 클래스를 작성하는 것과 같다. 다만 키워드로 class대신 interface를 사용한다는 것만 다르다. 클래스와 같이 접근제어자로 public 또는 default를 사용할 수 있다.
interface 인터페이스이름{
public static final 타입 상수이름 = 값;
public abstract 메서드이름(매개변수목록);
}
일반적인 클래스의 멤버들과 달리 인터페이스의 멤버들은 다음과 같은 제약사항이 있다.
- 모든 멤버변수는 public static final 이어야 하며, 이를 생략할 수 있다.
- 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다.
[단, static메서드와 디폴트 메서드는 예외 (JDK1.8부터) ]
인터페이스에 정의된 모든 멤버에 예외없이 적용되는 사항이기 때문에 제어자를 생략할 수 있는 것이며, 편의상 생략하는 경우가 많다. 생략된 제어자는 컴파일러가 자동적으로 추가해준다.
원래는 모든 메서드는 추상메서드여야 했는데, JDK1.8부터 인터페이스에 static메서드와 디폴트 메서드(default method)의 추가를 허용하는 방향으로 변경되었다. 실무에서는 아직 JDK1.8을 사용하지 않는 곳이 많기에 JDK1.8이전과 이후의 규칙을 모두 알고 있어야 한다.
7-3 인터페이스의 상속
인터페이스는 인터페이스로부터만 상속받을 수 있으며, 클래스와는 달리 다중상속, 즉 여러개의 인터페이스로부터 상속을 받는 것이 가능하다.
클래스와 마찬가지로 자손인터페이스는 조상인터페이스에 정의된 멤버를 모두 상속받는다.
[인터페이스는 클래스와 달리 Object클래스와 같은 최고조상이 없다.]
7-4 인터페이스의 구현
인터페이스도 추상클래스처럼 그 자체로는 인스턴스를 생성할 수 없으며, 추상클래스가 상속을 통해 추상메서드를 완성하는 것처럼, 인터페이스도 자신에 정의된 추상메서드의 몸통을 만들어주는 클래스를 작성해야 한다. 클래스의 확장 키워드 'extends'처럼 인터페이스는 구현한다는 키워드 'implements'를 사용한다.
만일 구현하는 인터페이스의 메서드 중 일부만 구현한다면 abstract를 붙여 추상클래스로 선언해야 한다. 상속과 구현을 동시에 할 수 도 있다.
인터페이스의 메소드에는 'public abstract'가 생략되었을 뿐, 항상 붙어있으니 이를 오버라이딩 시 접근 제어자를 반드시 public으로 해줘야 한다.
7-5 인터페이스를 이용한 다중상속
자바는 다중상속을 허용하지 않는다는 것이 단점으로 부각되는 것의 대응으로 '자바도 인터페이스를 이용하면 다중상소깅 가능하다' 라는 것일 뿐, 인터페이스가 다중상속을 위해서 존재하는 것은 아니다. 오히려 자바에서 인터페이스로 다중상속을 구현하는 경우는 거의 없다.
만일 두 개의 클래스로부터 상속을 받아야 할 상황이라면, 두 조상클래스 중에서 비중이 높은 쪽을 선택하고 다른 한쪽은 클래스 내부에 멤버로 포함시키는 방식으로 처리하거나 어느 한쪽의 필요한 부분을 뽑아 인터페이스로 만든 다음 구현하도록 한다.
인터페이스를 새로 작성하지 않고 클래스를 내부에 포함시키는걸로 충분하지만, 인터페이스를 이용하면 다형적 특성을 이용할 수 있다는 장점이 있다.
7-6 인터페이스를 이용한 다형성
인터페이스 역시 클래스의 조상이라 할 수 있으므로 해당인터페이스 타입의 참조변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있으며, 인터페이스 타입으로의 형변환도 가능하다.
인터페이스 Fightable을 클래스 Fighter가 구현했을 때, 다음과 같이 Fighter인스턴스를 Fightable타입의 참조변수로 참조하는 것이 가능하다.
Fightable f = (Fightable)new Fighter();
또는
Fightable f = new Fighter();
리턴타입이 인터페이스라는 것은 메서가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 것을 의미한다.
7-7 인터페이스의 장점
인터페이스를 사용하는 이유와 장점
-개발시간을 단축시킬 수 있다.
-표준화가 가능하다.
-서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다.
-독립적인 프로그래밍이 가능하다.
7-8 인터페이스의 이해
-클래스를 사용하는 쪽(User)과 제공하는 쪽(Provider)이 있다.
-메서드를 사용(호출)하는 쪽(User)에서는 사용하려는 메서드(Provider)의 선언부만 알면 된다.(내용은 몰라도 된다.)
7-9 디폴트 메서드와 static메서드
디폴트 메서드
디폴트 메서드는 앞에 default를 붙이며, 추상 메서드와 달리 일반 메서드처럼 몸통{}이 잇어야 한다. 디폴트 메서드 역시 접근 제어자가 public이며, 생략 가능하다.
새로 추가된 디폴트 메서드가 기존 메서드와 이름이 중복되어 충돌하는 경우
1. 여러 인터페이스의 디폴트 메서드 간의 충돌
- 인터페이스를 구현한 클래스에서 메서드를 오버라이딩해야 한다.
2. 디폴트 메서드와 조상클래스의 메서드 간의 충돌
- 조상 클래스의 메서드가 상속되고, 디폴트 메서드는 무시된다.