# 인터페이스
- 구현이 어떻든 깊이 학습할 필요없이 원하는 기능을 수행하고 결과 값을 제대로 받게 해주는 간편한 상호작용 기능
- 프레임워크의 내부 구성 학습 없이, 그저 지원해주는 메서드를 이용하여 간편하게 프로젝트를 개발할 수 있게 해준다
## 일상 생활에서 인터페이스
- 문 손잡이: 문을 쉽게 열고 닫을 수 있게 해주는 인터페이스
- 전등 스위치: 조명을 켜고 끌 수 있게 해주는 인터페이스
- 자동차 대시보드: 차량의 속도, 연료 및 기타 중요한 데이터에 대한 정보를 표시하는 복잡한 인터페이스
- 스마트폰 화면: 터치 스크린은 다양한 앱과 기능에 액세스할 수 있는 직관적인 인터페이스
- 키보드/마우스: 컴퓨터와 상호작용을 하기 위한 인터페이스
- 텔레비전 리모콘: 채널을 변경하고 볼륨을 조절하고 텔레비전의 다른 기능을 제어할 수 있게 해주는 인터페이스
## 자바에서의 인터페이스

- 자바에서 클래스들이 구현해야하는 동작을 지정하는 용도로 사용되는 추상 자료형
- 자바에서 다중상속을 간접적으로 가능하게 해준다
- 자바에서는 기본적으로는 다중상속을 지원하지 않는다
- 인터페이스는 클래스와 별도로 구현 객체가 같은 동작을 한다는 것을 보장하기 위해 사용하는 것에 초점이 맞춰져있다.
- 상속받은 인터페이스의 추상 메서드를 구현하지 않으면 컴파일 오류 발생
- 추상 클래스 상속과 전혀 다르지 않다
- 미구현으로 인한 컴파일 오류를 발생시켜 실수를 방지해준다
- 메서드 이름 오타 or 부모클래스의 메서드 이름만 바꾸고 자식 클래스는 손대지 않는 경우
- Java에서는 `@Override`라는 어노테이션을 제공한다
- 이 어노테이션을 메서드 위에 사용하면 상속받은 메서드를 구현하겠다는 의미
- 만약 부모 클래스에 같은 이름의 메서드가 없으면 오류 발생
- 인터페이스는 `public` 메서드만 가능
- 누구라도 보고 명령할 수 있는 동작
- 인터페이스는 다중 상속이 가능 (클래스 다중상속은 불가능)
- 메서드가 중복되더라도 오버라이딩되지 않기 때문에 실체가 겹칠 위험이 없음
- 아무리 복잡하게 상속 구조를 해도 구현은 하나 뿐
- 인터페이스는 두 실체가 중복되어도 상속받은 클래스가 구현만 제공하면 됨
- 단 반환형만 다르면 컴파일 오류가 난다
- 두 함수를 다 구현할 방법이 없기 때문에
- 반환형만 다른 경우는 올바른 함수 오버로딩이 아님
- **인터페이스는 다중 상속의 해결법**
> 인터페이스는 특수한 형태의 클래스다
>
> - 어떤 상태도 없음
> - 동작의 구현도 없음
> - 동작의 시그내처만 있음
> - 이런 특징 때문에 클래스와는 약간 다른 규칙을 따른다
### 인터페이스 문법

- 인터페이스를 작성하는 것은 추상 클래스를 작성하는 것과 같다고 보면 된다. (추상 메서드 집합)
- `class` 대신 `interface`라는 키워드를 이용하여 선언할 수 있으며 메소드 시그니처와 상수 선언만을 포함할 수 있다
- 인터페이스의 모든 상수는 `public static final`이며, 모든 메서드는 `public abstract` 이다.
- 인터페이스에 선언 시 편의상 생략이 가능하다.
- `default` 키워드를 사용하여 구현부가 있는 메서드를 만들어줄 수 있다.
- 구현체에게 수정 없이 광역으로 함수를 만들어주고 싶을 때 사용된다
- `default` 메서드가 다중 상속 문제로 인해 충돌 되는 경우 오버라이딩을 해야 한다
- 클래스가 인터페이스를 상속받을 때는 `implements` 키워드를 사용한다
- 인터페이스가 인터페이스를 상속받을 때는 `extends` 키워드를 사용한다
### 인터페이스 정의
```java
public interface 인터페이스이름 {
// 상수
public static final 타입 상수이름 = 값;
타입 상수이름 = 값; // public static final 생략 가능
// 메서드
public abstract 반환타입 메서드이름(매개변수목록);
반환타입 메서드이름(매개변수목록); // public abstract 생략 가능
// default 메서드
public default 반환타입 메서드이름(매개변수목록) { ... }
반환타입 메서드이름(매개변수목록) { ... } // public default 생략 가능
}
```
```java
public interface Car {
// 상수
int WHEEL_COUNT = 4;
// 메서드
void run();
// default 메서드
void stop() {
System.out.println("차를 멈춤");
// Code to stop the car
}
}
```
### 인터페이스 상속 (클래스가 인터페이스를 상속받을 때)
```java
public class 클래스이름 implements 인터페이스이름 { // `implements` 키워드 사용하여 인터페이스 상속
// 인터페이스에 선언된 추상 메서드 구현
// 인터페이스에 선언된 default 메서드 재정의
}
```
```java
public class Sonata implements Car {
@Override
public void run() {
System.out.println("소나타가 달립니다.");
}
@Override
public void stop() {
System.out.println("소나타가 멈춥니다.");
}
}
```
### 인터페이스 상속 (인터페이스가 인터페이스를 상속받을 때)
```java
public interface 인터페이스이름 extends 인터페이스이름 { // `extends` 키워드 사용하여 인터페이스 상속
// 인터페이스에 선언된 추상 메서드 구현
// 인터페이스에 선언된 default 메서드 재정의
}
```
```java
public interface HybridCar extends Car {
// 인터페이스에 선언된 추상 메서드 구현
// 인터페이스에 선언된 default 메서드 재정의
}
```
## 인터페이스는 다중 상속이 가능하다
- 자바에서 클래스는 다중상속이 되지 않는다.
- 다중 상속은 잘못 사용할 경우 코드의 복잡도가 증가하고 가독성이 떨어지기 때문에 자바에서는 다중상속을 지원하지 않는다.
- C++에서는 다중상속이 가능하다
- 인터페이스는 구현된 내용이 없기 때문에 다중 상속이 가능하다
- 인터페이스는 구현된 내용이 없고 구현되어야 할 메서드의 이름만 존재하기 때문에 다중 상속이 가능하다

```java
public class 클래스 이름 implements 인터페이스1, 인터페이스2, ... {
// 인터페이스에 선언된 추상 메서드 구현
// 인터페이스에 선언된 default 메서드 재정의
}
```
```java
public interface Car {
void run();
void stop();
}
public interface ElectricCar {
void charge();
}
public class Sonata implements Car, ElectricCar {
@Override
public void run() {
System.out.println("소나타가 달립니다.");
}
@Override
public void stop() {
System.out.println("소나타가 멈춥니다.");
}
@Override
public void charge() {
System.out.println("소나타가 충전됩니다.");
}
}
```
---

```java
public interface 인터페이스이름 extends 인터페이스1, 인터페이스2, ... { // `extends` 키워드 사용하여 인터페이스 상속
// 인터페이스에 선언된 추상 메서드 구현
// 인터페이스에 선언된 default 메서드 재정의
}
```
```java
public interface HybridCar extends Car, ElectricCar {
// 인터페이스에 선언된 추상 메서드 구현
// 인터페이스에 선언된 default 메서드 재정의
}
```
### 자바 버전별 인터페이스 기능

- 자바 버전별로 인터페이스의 기능이 추가되었다
- 자바 8에서는 `default` 메서드와 `static` 메서드를 인터페이스에 추가할 수 있게 되었다
- `default` 메서드는 구현체에게 수정 없이 광역으로 함수를 만들어주고 싶을 때 사용된다
- `static` 메서드는 인터페이스의 메서드를 사용하기 위해 인스턴스를 생성할 필요가 없을 때 사용된다
- 자바 9에서는 `private` 메서드를 인터페이스에 추가할 수 있게 되었다
- `private` 메서드는 인터페이스 내부에서만 사용되는 메서드이다
- `default` 메서드를 구현할 때 사용되는 메서드이다
- `private` 메서드는 인터페이스를 구현하는 클래스에서는 사용할 수 없다
### 컬렉션에서의 인터페이스 활용 예시

# 추상클래스 vs 인터페이스
- 인터페이스나 추상클래스나 둘이 똑같이 추상 메소드를 통해 상속/구현을 통한 메소드 강제 구현 규칙을 가지는 추상화 클래스이다.
- 다만 이 둘은 각각 고유의 몇몇 특징들을 가지고 있는데, 이러한 특징으로 인해 각각 사용처가 갈리게 된다. 또한 기능적인 부분 뿐만 아니라 인터페이스와 추상클래스가 내포하고있는 논리적인 의미로서도 사용처가 나뉜다.
## 추상클래스를 사용하는 경우
- 상속 받을 클래스들이 공통으로 가지는 메소드와 필드가 많아 **중복 멤버 통합**을 할때
- 멤버에 `public` 이외의 접근자(`protected`, `private`) 선언이 필요한 경우
- `non-static`, `non-final` 필드 선언이 필요한 경우 (각 인스턴스에서 상태 변경을 위한 메소드가 필요한 경우)
- 요구사항과 함께 구현 세부 정보의 일부 기능만 지정했을 때
- 하위 클래스가 오버라이드하여 재정의하는 기능들을 공유하기 위한 상속 개념을 사용할 때
- 추상 클래스는 이를 상속할 각 객체들의 공통점을 찾아 추상화시켜 놓은 것으로, 상속 관계를 타고 올라갔을 때 같은 부모 클래스를 상속하며 부모 클래스가 가진 기능들을 구현해야할 경우 사용한다.
## 인터페이스를 사용하는 경우
- 어플리케이션의 기능을 정의해야 하지만 그 구현 방식이나 대상에 대해 추상화 할 때
- **서로 관련성이 없는 클래스**들을 묶어 주고 싶을때 (형제 관계)
- **다중 상속**을 통한 추상화 설계를 해야할때
- 특정 데이터 타입의 행동을 명시하고 싶은데, 어디서 그 행동이 구현되는지는 신경쓰지 않는 경우
- 클래스와 별도로 **구현 객체가 같은 동작을 한다는 것을 보장**하기 위해 사용
## 인터페이스 + 추상클래스를 사용하는 경우

- 추상 클래스의 중복 멤버 통합과 인터페이스의 다중 상속 기능을 동시에 사용하기 위해서 종종 같이 사용되곤 한다
---
### 구체클래스 vs 인터페이스
| 구체 클래스 | 인터페이스 |
| -------------------------------- | --------------------------------- |
| 상태와 동작을 모두 포함 | 동작에 대한 설명만 포함 |
| 동작에 다양한 접근권한 부여 가능 | 모든 동작은 public |
| 구체클래스로부터 개체 생성 가능 | 인터페이스로부터 개체 생성 불가능 |
| 다중 상속의 부모가 될 수 없음 | 다중 상속의 부모가 될 수 있음 |