> For the complete documentation index, see [llms.txt](https://docs.sysout.co.kr/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sysout.co.kr/base-language/java/advanced/oop.md).

# 객체 지향 프로그래밍

## 객체 지향 프로그래밍(OOP)

OOP(Object Oriented Programming), 객체 지향 프로그래밍은 단어 뜻 그대로 `객체를 적극적으로 활용하여 프로그래밍`하는 방식을 말한다. 독립된 객체(Object)들을 만들어 서로 상호작용하며 현실 세계와 유사한 형태로 프로그래밍 하는 것을 목표로 하는 설계 방법을 의미한다.

객체들은 여러 가지의 정보의 혼합으로 만들어지며, 자바에서는 이를 만들기 위해서 `class`라는 형태를 제공한다.

### 객체의 이해

우리 현실에 존재하는 물건들 역시 객체로 분류되기 때문에 우리는 객체에 대해서 잘 알고 있다. 다음 사진을 보면 본인의 객체에 대한 이해도를 파악할 수 있다.

![흔히 볼 수 있는 메신저 화면](https://4208234536-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_TNZwLuHV9ipYLbvRq%2F-MeOE4wVf_Jy7JXCgNdY%2F-MeOEsCENW3KxRdNkjN7%2Fimage.png?alt=media\&token=6436801a-18f1-4011-8a24-c2446dc23b7e)

위의 내용은 카카오톡(Kakaotalk) 메신저의 채팅 내용의 일부이다. **화면에서 메세지(Message)라고 할 수 있는 요소**는 몇 개인가?

.\
.\
.\
.\
.\
.\
.

4개라고 대답했다면 객체가 무엇인지 정확하게 파악하고 있는 것이다. 화면에 존재하는 많은 데이터들을 연관있는 것끼리 분류하여 하나의 단위로 인식하고 있다는 의미이기 때문이다.

### 클래스의 이해

이러한 객체(메세지)를 만들기 위해서는 메세지가 어떠한 데이터들로 이루어져 있는지 정의해야 한다. 명확하게 정의하지 않는다면 기준이 없어서 사람들마다 기준이 달라질 수 있기 때문이다.

* 메세지(Message)
  * 프로필사진(profile)
  * 보낸사람(sender)
  * 내용(content)
  * 보낸시각(time)
  * 안읽은사람수(people)

우리가 알고 있는 지식과 화면의 내용을 조합해보면 메세지는 여러 데이터들로 구성되어 있음을 알 수 있다. 자바에서 데이터들은 각각의 자료형(Data type)을 가지고 있으며, 우리는 프로필사진을 제외한 모든 구성요소들의 데이터를 정의할 수 있다.

* Message
  * profile(???)
  * sender(String)
  * content(String)
  * time(String)
  * people(int)

`String`과 , `int`같은 데이터들은 **더 이상 분해될 수 없는** 데이터이므로, 프로필 사진만 제외한다면 우리는 메세지가 어떠한 형태의 데이터로 이루어졌는지 알고 있다는 내용이 된다.

따라서 JVM이 이해할 수 있도록 내가 알고 있는 형태를 정의해줄 필요가 있으며, 이를 `class`라고 한다. `class`를 만들고 구성요소를 적절히 배치하면 JVM이 이를 해석하여 프로그램 상에서 객체를 생성하고 사용한다.

`class`를 잘 구성하는 것이 객체 지향적인 프로그래밍을 잘 하는 비결이며, 이를 위한 각종 문법들이 준비되어 있다.

### 객체 지향의 특징

객체 지향은 다음의 특징을 가진다.

* 은닉화
* 캡슐화
* 상속
* 추상화
* 다형성

### 캡슐화

캡슐화란 객체의 기능을 만들 때 이용자에게 최소한의 필요한 기능만 노출시켜 내부 상태를 알지 못해도 이용할 수 있도록 만드는 디자인 기법이다.

일반적으로 자판기를 예로 많이 드는데, 사용자가 자판기의 내부 구조는 모르지만 외부에 드러나있는 투입구, 버튼, 투출구만 이용하여 온전히 사용할 수 있도록 구성되어 있기 때문이다.

우리가 객체를 디자인할 때 캡슐화를 잘 수행한다면 객체는 자판기처럼 이용자가 내부 구조보다 기능에 초점을 맞추어 사용할 수 있게 된다.

이를 위해서는 접근 제한을 통해 데이터를 보호하는 은닉화 구조가 먼저 구현되어야 한다.

### 상속

상속은 클래스 그룹을 효율적으로 만들기 위한 기법이다. 예를 들어 다음 두 개의 형태를 만든다고 가정해본다.

![](https://4208234536-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_TNZwLuHV9ipYLbvRq%2F-MeOE4wVf_Jy7JXCgNdY%2F-MeOFMJ2dmzhTNJ5jgPT%2Fimage.png?alt=media\&token=2bc0bbc0-8efb-456c-8e28-aecbaaa35077)

중복되는 부분이 많기 때문에 공통점만 추려 다음과 같은 구조를 만들 수 있다.

![](https://4208234536-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_TNZwLuHV9ipYLbvRq%2F-MeOE4wVf_Jy7JXCgNdY%2F-MeOFQ2Jcpfl056WX4tA%2Fimage.png?alt=media\&token=f840b40c-1e84-4b90-a435-1e8b8d3096f4)

위와 같은 구조를 상속 구조라고 하며, 다른 휴대전화들이 추가되더라도 공통된 부분을 이용할 수 있기 때문에 좀 더 빠르고 효율적으로 개발할 수 있는 특징이 생긴다.

### 다형성

다형성이란 **상속 관계에서 대표 형태로 하위 형태를 표현하는 방법**을 말한다. 세부적인 이론 다형성 관련 문서에서 다루기 때문에 개념적으로만 살펴본다.

어떤 치킨집에서 메뉴판이 다음과 같다고 가정해본다.

![](https://4208234536-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_TNZwLuHV9ipYLbvRq%2F-MeOE4wVf_Jy7JXCgNdY%2F-MeOG8ZGYLMrSCS-coy9%2Fimage.png?alt=media\&token=22b68614-23be-4b6a-9767-3b3bdd944edd)

가게 이름만 보면 `치킨`을 파는 가게인데 실제로 판매하는 것은 `후라이드 치킨`, `양념 치킨`, `간장 치킨`인 것을 알 수 있다. 이것이 가능한 이유는 프로그래밍적으로 봤을 때 다음 구조를 가지고 있기 때문이다.

![](https://4208234536-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_TNZwLuHV9ipYLbvRq%2F-MeOE4wVf_Jy7JXCgNdY%2F-MeOGR9_JKnkLNBPqv19%2Fimage.png?alt=media\&token=603fcff5-bf88-4c5b-b3c2-86d07e118f02)

![](https://4208234536-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_TNZwLuHV9ipYLbvRq%2F-MeOE4wVf_Jy7JXCgNdY%2F-MeOGTPZkcegHfnCdCKs%2Fimage.png?alt=media\&token=d1c8d091-f8e2-4985-b408-bd750264f617)

만약 간판을 `후라이드치킨`집이라고 했다면 양념치킨이나 간장치킨은 판매하지 못했을 것이다. 이처럼 다양한 형태를 하나로 묶어서 표현하도록 하는 기술을 다형성(多形性)이라고 한다.
