0. 결론
- Spring과 객체지향 프로그래밍의 핵심은 다형성에 있다.
- 다형성을 객체지향 프로그래밍의 특성 중 하나라고 말하지만, 다형성으로 인해 객체지향 프로그래밍의 개념이 완성된다.
- 그렇다면 다형성이 무엇인지, 왜 객체지향의 핵심인지 알아보자.
1. 객체지향 프로그래밍(OOP)이란?
- 객체지향 프로그래밍이란,
→ 독립적인 단위(객체)가 협력하여 데이터를 처리하는 프로그램 구조를 갖는 것
→ 독립적인 단위(객체) 간의 관계가 유연하여 부품을 교체하듯, 프로그램의 구조변경이 쉬운 것
- 즉, 자동차를 만드는 것처럼 프로그램(App)을 만드는 것이다.
- 자동차는 수많은 부품의 조합으로 이루어진 결과물이다.
- 이처럼 코드를 역할에 따라 분리하고, 하나의 부품으로써 조합하여 App이라는 결과물로 만드는 방식을 말한다.
a) 객체지향의 4가지 특징
- 객체지향에는 추상화, 캡슐화, 상속, 다형성이라는 대표적인 4가지 특징이 존재한다.
- 이 4가지 특징은 모두 다형성으로부터 파생된 개념이다. 왜 그럴까?
- 그 답은 아래에서 찾을 수 있다.
2. 다형성이란?
- 다형성을 이해하기 위해서는 먼저 역할과 구현에 대해 알아야 한다.
a) 역할과 구현
- 간단한 예시를 들어보자.
- 영화를 만들기 위해서는 '배역'이 있어야 하고, 배역을 연기하는 '배우'가 있어야 한다.
- 여기서 배역은 역할이고, 배우는 구현이다.
- 즉, 배역(역할)이 변하지 않는다면 어떤 배우가 와서 연기를 하든 관객(client)에게 전달되는 영화의 스토리는 변하지 않는다.
- 또 다른 예시를 살펴보자.
- 컵의 기능(= 역할)은 음료를 따르고 마시기 위한 도구다.
- 컵의 모양(= 구현)이 달라도 컵의 기능(= 역할)은 변하지 않는다.
- 머그 컵이든, 텀블러든, 유리컵이든, 컵을 사용하는 사람(= client)에게 컵은 동일한 기능을 한다.
- 여기서 역할은 컵의 기능(음료를 따르고 마시기 위한 도구) / 구현은 컵의 모양(머그 컵, 텀블러, 유리컵)이다.
b) Java에서 역할과 구현을 표현하는 방법
- 이 개념을 Java 프로그래밍에 적용하면
→ 역할은 interface
→ 구현은 interface를 상속받아 내부 메소드를 override 한 클래스가 된다.
- 즉, 역할이 고정되어 있다면 구현의 결과와는 상관없이 코드의 역할은 동일하다는 것이 다형성의 의미다.
- 더불어, 구현 방식과 상관없이 역할은 동일하기 때문에 Client가 사용함에 있어 아무런 영향을 주지 않는다는 것이 핵심이다.
3. 역할과 구현의 적용
- 그렇다면 역할과 구현을 코드에 적용하면 어떻게 될까?
- Client의 요청에 따라 실행 시점에서 유연하게 코드를 변경할 수 있어야 한다.
- 그러므로 client가 해당 기능 또는 프로그램을 사용하는 데 아무런 문제가 없어야 한다.
→ 코드의 역할은 동일하기에, 어떤 구현체(= 코드)를 사용하더라도 동일한 기능을 수행할 수 있어야 한다.
- 말이 어렵다. 쉽게 예시를 들어보자.
- 쇼핑몰 웹사이트를 생각해보자.
- 쇼핑몰은 다양한 할인 정책을 제공한다. 카드 할인, 쿠폰 할인, 멤버십 할인 등 말이다.
- 다양한 할인 정책 중 소비자(사용자, client)가 원하는 한 가지 할인 방식을 선택할 수 있다.
- 그러므로 client의 선택에 따라 적용되는 할인 정책이 달라지게 된다.
- 위에서 설명한 예시가 바로 client의 요청 시점에 따라 코드를 유연하게 변경하는 것이다.
- 더불어 client가 어떤 선택을 하든, 할인 혜택을 받는 것에는 아무런 영향을 주지 않는다.
→ 코드의 역할은 동일하기에, 어떤 구현체(= 코드)를 사용하더라도 동일한 기능을 수행할 수 있어야 한다.
- 위의 예시에서 역할은 '할인' 그리고 구현은 '카드 할인', '쿠폰 할인', '멤버십 할인'이다.
4. 다형성과 객체지향의 특징
- 앞서 객체지향의 특징 4가지(추상화, 캡슐화, 상속, 다형성)는 모두 다형성에서 파생된 개념이라고 말했다.
- 이를 이해하기 쉽도록 풀어보려고 한다.
a) 추상화(Abstraction) - 역할을 정의하는 방법
- 추상화란 역할을 정의하는 것이다. (여기서 역할은 다형성에서 설명한 역할이다)
- 조금 더 쉽게 설명하자면, Java에서 interface를 만드는 행위를 의미한다.
- interface에는 객체의 공통적인 속성과 기능만을 명시하고 실질적인 내부 로직은 구현하지 않는다.
- 예를 들어, 자판기를 추상화한다고 해보자.
ex) 모든 자판기에는 다음과 같은 공통 기능이 있다.
→ 돈을 받는다.
→ 물건을 선택한다.
→ 선택된 물건을 반환한다.
→ 거스름돈이 있다면 반환한다.
ex) 모든 자판기에는 다음과 같은 공통적인 속성이 있다.
→ 판매하는 물건의 가격
→ 판매하는 물건의 이름
→ 판매하는 물건의 품절여부
→ 사용자가 삽입한 금액
→ 거스름 돈의 금액
- 이처럼 공통적인 기능과 속성만 명시하는 것을 추상화라고 한다.
- 단순히 명시만 하는 이유는 어떤 자판기냐에 따라 물건도, 물건의 가격도, 물건의 이름도 달라지기 때문이다.
- 즉, 실질적인 세부사항은 구현할 때 정의하는 것이다.(= interface method override)
- 이렇게 자판기 interface가 생성되었다.
b) 상속 (Inheritance) - 역할의 정의
- 상속은 역할을 구현하는 과정에서 발생하는 특징이다.
- 앞서 추상화한 자판기를 기반으로 특정한 물건을 판매하는 자판기를 만든다고 해보자.
- 어떤 자판기를 만들더라도 앞서 추상화한 자판기의 공통적인 기능과 속성들을 그대로 가져와 쓰는 것이 편하지 않은가?
- 이처럼, 어떤 클래스 or 인터페이스의 기능과 속성을 그대로 가져와 사용하는 것을 상속이라고 말한다.
- 상속이라는 말 그대로 물려받는 것이다.
- 이렇게 자판기 interface를 상속받은 자판기 class가 생성되었다.
c) 캡슐화 (Encapsulation) - 역할 구현
- 캡슐화란, Java에서 클래스를 만드는 것이다.
- 즉, 추상화를 통해 어떤 객체를 정의한 뒤 해당 객체의 속성과 기능을 구현하고 하나로 묶어주는 과정이다.
- 캡슐화에는 정보은닉이라는 효과가 있는데, 이는 외부에서 클래스 내부의 변수 값을 직접 접근 / 변경할 수 없게 하는 것이다.
- 즉, class 접근 지정자를 통해 구현된다.
- 앞서 자판기를 추상화했다. 그리고 추상화된 자판기를 상속받은 자판기 class를 생성했다.
- 이를 이용하여 과자 자판기를 만들려고 한다. 그러므로 과자 자판기만의 특징을 구현한다. ex) 과자만 판매한다.
- 캡슐화를 비유를 통해 한번 더 설명하자면 다음과 같다.
- 과자 자판기를 만들었지만, 누군가 자판기의 문을 열고 과자를 꺼내갈 수 있지 않은가?
- 자판기 문을 관리자 외 함부로 열지 못하도록 자물쇠를 걸어둔다.
- 이렇게 과자 자판기 class가 생성되었다.
5. 다형성과 객체지향의 관계
- 지금까지 설명한 것을 다시 한번 정리해보자.
- 다형성이란, 역할과 구현을 분리하여 코드를 작성하는 것이고, 그 과정에서 추상화, 상속, 캡슐화라는 특징이 등장한다.
- 다형성으로 인해 역할은 동일하지만 다른 기능을 가진 코드를 부품처럼 교체하여 사용할 수 있으며,
- 동시에 해당 기능을 사용하는 client에게는 아무런 영향을 주지 않는다.
→ 자판기의 사용 방식은 동일하다. 자판기의 내용물이 바뀐다고 사용 방식이 변하는 것은 아니다.
- 이처럼 다형성으로 인해 객체지향을 구현할 수 있으며, 객체지향 프로그래밍의 개념이 완전해진다.
- 즉, 다형성을 기반한 프로그래밍이 객체지향 프로그래밍인 것이다.
'Back-end > Spring 개념' 카테고리의 다른 글
6. Spring Container의 다형성 (0) | 2022.02.01 |
---|---|
5. Spring Container (0) | 2022.01.31 |
4. Spring을 사용하는 이유 (1) | 2022.01.27 |
3. SOLID 원칙 (0) | 2022.01.26 |
1. Maven과 Gradle이란? (0) | 2022.01.23 |
댓글