# 추상 클래스와 인터페이스의 차이

## 인터페이스의 기능이 추가 되면서 추상 클래스와 쓰임이 혼란스러워 지고 있다.

Java 에서 다형성을 다루는 방법으로 제공하는 `추상 클래스`와 `인터페이스`의 동작 메커니즘은 격차가 많이 줄어들었다.

* default 메서드의 등장으로 인터페이스도 구현을 가질 수 있게 되었다. 따라서 템플릿 메서드 패턴도 인터페이스로 충분히 구현할 수 있게 되었다. (java 8)
* private 메서드를 인터페이스에서 사용할 수 있게 되어 인터페이스로도 캡슐화(정보 은닉)가 가능하다. (java 9)

그래서 그 개념을 혼동하거나 비슷한 것으로 착각하는 경우가 있다. 그러나 근본적으로 `클래스`와 `인터페이스`라는 큰 개념의 차이가 있다.&#x20;

## 클래스와 인터페이스의 개념 차이

한마디로 '**쓰임의 목적'** 에서 이 둘의 개념은 분명히 다르고 그 쓰임에 따라 적절하게 사용해야 한다고 생각한다.

### 쓰임(사용 하는 목적)에 따른 구분

* **클래스(추상클래스)**&#xB294; **확장**
* **인터페이스**는 **계약(약속)**

위와 같이 설명해도 크게 와닿지 않는다면...!

### 클래스 (상속)

클래스의 상속은 나의 코드를 물려주는 것 + 조금 달라지는 부분을 재정의하여 사용하도록 하는 것. \
또는, 서브 클래스에서 발견된 공통된 부분을 슈퍼 클래스로 공통화 하여 중복 코드를 제거하는 목적으로 주로 사용된다.

### 인터페이스

ISP (Interface Segregation Principle) 원칙을 들어봤을 것이다. 보통 이 원칙은 클래스 입장에서 클래스가 구현하는 인터페이스는 최소화 되어야 한다고 설명하는 데, 사실은 "**인터페이스는 간결하고 가능한 한 작게 설계되어야 한다."** 는 말이다.

구현의 복잡성은 **조합**으로 해결한다. 그래서 인터페이스는 **다중 상속**을 지원한다. (다중 상속은 Java 에서 상속과 인터페이스를 구분하는 주요한 특징이다.)

## 템플릿 메서드 패턴을 구현할 때 어떤 것을 써야 하는가?

템플릿 메서드 패턴의 경우에는 템플릿 코드(자주 변경되지 않는 코드)가 구체적이고 큰 기능일 가능성이 높다. 따라서, 자주 변경되지 않는 구체적이고 큰 기능을 자식에게 물려주는 **상속**의 성격이 더 강하다고 생각한다.

또한, 만약에 템플릿 코드(물려주는 코드) 자체의 변경이 발생한다면 재정의 된 서브 클래스들에게 변경에 의한 영향을 크게 미칠 수 있게 된다. (사이드 임펙트)

{% hint style="info" %}
이런 맥락에서 java 17 에서는 `sealed class` 를 제공한다. 부모 쪽에서 상속 가능한 클래스를 지정하는(제한하는) 기능이다. [java version](/second-brain/second-brain/java/java-version.md#java-17)
{% endhint %}

**즉, 변경에 대한 리스크의 주체가 부모 쪽에 있는 것이다.** 추상 클래스는 이런 리스크를 좀 더 명확하게 표현해준다고 생각한다. (추상 클래스를 변경하면 서브 클래스들에 영향이 없는 지 잘 확인해봐야해\~ 이런 느낌)

{% hint style="info" %}
템플릿 메서드 패턴에서 인터페이스로 구현하는 것을 안티 패턴으로 보는 이유

인터페이스는 간결하고 가능한 한 작게 설계 되어야 한다. 따라서 구체적이고 큰 기능이 되는 템플릿 메서드를 인터페이스로 구현하는 것은 적절하지 못하다.

인터페이스는 **default 메서드의 남용**을 하지 않고 본래의 의도인 **제약 및 약속의 목적**으로만 사용한다면 변경에 대한 사이드 임팩트는 거의 없을 것이다.

템플릿 메서드 패턴에서 템플릿을 default 메서드로 구현하는 것은 기존에 제공된 인터페이스의 하위 호환성을 위해서 도입한 본래의 목적과는 다르게 남용되어 쓰이는 것으로 생각된다.

default 메서드는 내가 구현한 것이 아닌 내가 설계한 인터페이스를 사용하는 어떤 알 수 없는 구현체들 간 호환성을 위해 만들어졌다.
{% endhint %}

{% hint style="info" %}
물론 뭐든지 잘 알고 쓰면 문제는 없다.

다만, **나만 잘 알고 쓰면 문제 된다.** 그러니 상속의 쓰임이 필요하다면 추상 클래스를 사용하도록하자!
{% endhint %}

[template method pattern](/second-brain/second-brain/design-pattern/template-method-pattern.md#undefined-4)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://programmer-jjy.gitbook.io/second-brain/technical/technical-curiosity/abstract-vs-interface.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
