자바는 클래스 간의 다중 상속을 허용하지 않는다.
A
/ \
B C
\ /
D
D는 B와 C 둘다 상속받지만, method()라는 메소드가 B와 C에 각각 다르게 정의돼있을 때, D는 어떤 method()를 상속받아야 할지 혼란이 생긴다. 이를 다이아몬드 문제라고 한다.
인터페이스에는 구현 내용이 없다. 인터페이스에는 method명만 선언하고, 실행문은 존재하지 않는다. 그렇기 때문에 B와 C가 같은 이름의 method()을 가지고 있어도 충돌될 내용이 없기 때문에 문제될 것이 없다.
하나의 클래스는 두개 이상의 인터페이스를 implements를 할 수 있다. 이를 통해 인터페이스로서 타입을 여러개 가질 수 있도록 한다.

public class 구현클래스명 implements 인터페이스A, 인터페이스B{
//모든 추상 메소드 재정의
}
인터페이스A 변수 = new 구현클래스명();
인터페이스B 변수 = new 구현클래스명();
public interface 자식인터페이스 extends 부모인터페이스1, 부모인터페이스2{}
implements 한 모든 인터페이스의 abstract method를 정의해줘야 한다. A와 B에 동일한 메소드가 있을 때 하나의 메소드명으로만 재정의해주면 된다.
public abstract class Animal{
//FIELD
//CONSTR
//(abstract) METHOD
}
public interface Sleepable{
//public static final FIELD
//abstract METHOD
}
public class Bear extends Animal{
//생성자
@Override
//구현메소드
}
public class Bear implements Sleepable{
@Override
//구현메소드
}
클래스 상속과 인터페이스 구현을 동시에 선언할 수 있다.
public class D extends C implements A,B{}
상속은 코드 재사용, 다형성을 구현하는 장점이 있다. 하지만 클래스에서는 다중 상속을 허용하지 않기 때문에 상속을 구현할 때는 보통 인터페이스를 사용하는 추세이다. 문법 자체는 클래스의 상속과 다른 점이 거의 없지만, 실무에서는 인터페이스를 사용한 다형성을 더 많이 사용한다. 인터페이스를 사용하면 객체 간 결합도를 낮출 수 있고, 구현체를 쉽게 교체할 수 있는 유연한 설계가 가능해진다.

자료 결합도: 메소드가 필요한 데이터만 주고받는 방식
| 구분 | 클래스 | 인터페이스 |
|---|---|---|
| 연결 방식 | 구체적인 구현 클래스에 의존 | 추상적인 기능에만 의존 |
| 변경 유연성 | 구현 클래스 변경 시 의존 코드 영향 받음 | 구현체가 바뀌어도 의존 코드 영향 없음 |
| 결합도 측면 | 상대적으로 높음 | 훨씬 낮음 |
인터페이스를 사용하면 약속된 기능(메소드 시그니처)만 의존하고, 구현체가 무엇이든 상관하지 않기 때문에 결합도를 낮출 수 있다. 결합도가 낮아야 유지보수 측면에서 좋은 소프트웨어를 가지고 있다고 한다.
List<String> list = new ArrayList<>();
List는 인터페이스이고, ArrayList는 그 구현체이다. List 타입으로 선언하고, ArrayList 객체를 참조하면, 나중에 다른 구현체로 바로 교체해줄 수 있다.
list = new LinkedList<>();
위와 같이 list에 LinkedList를 대입해도 프로그램 전체 코드를 수정할 필요 없이 List 인터페이스의 모든 메소드를 사용하면 된다.
List라는 하나의 타입만 바라보고, 실제 어떤 구현 객체인지는 나중에 선택/변경이 가능하다.