서론
객체 지향의 특징 4가지를 정리할 예정입니다.
1. 캡슐화
2. 추상화
3. 상속
4. 다형성
객체 지향과 캡슐화가 무엇인지는 이전 글에 작성했습니다.
https://langeasy.tistory.com/106
[Java] 객체 지향 언어의 특징 - 캡슐화(Encapsulation)
서론객체 지향의 특징 4가지를 정리할 예정입니다.1. 캡슐화2. 상속3. 다형성4. 추상화 우선 캡슐화 설명에 들어가기에 앞서 객체 지향이란 무엇일까? 객체 지향이란? from 객체 지향의 창조자 :
langeasy.tistory.com
캡슐화를 공부했으면 아시겠지만, 캡슐화를 했기 때문에 추상화, 상속, 다형성이라는 특징을 쓸 수 있는겁니다.
특징 4가지가 모두 유기적으로 연결되어있어 그말이 그말 같지만
보면 볼 수록 유연한 프로그래밍 개발을 할 수 있는 좋은 구조임에 틀림없습니다!
추상화란?
추상화란 무슨 의미를 갖고 있는 단어일까요?
사전적의미
우선 사전적인 단어는 다음과 같습니다.
추상화(抽象化)- 추상적인 것으로 됨. 또는 그렇게 만듦.
추상적(抽象的) :
1. 일정한 형태와 성질을 갖추고 있지 않은 것.
ex> 예시 있으면 알려주세요.
2. 구체적이지 않아 막연하고 일반적인 것.
ex> " 나 오늘 저녁 맛있는거 먹을거야."
객체 지향에서 의미
일반적인 설명
그럼 객체 지향 관점에서 추상화라는 단어는 무슨 의미를 갖고있을까?
1. 객체가 기능을 어떻게 수행하는지 가리는 행위
2. 객체의 공통적인 속성과 기능을 추출하여 정의하는 것
객체가 기능을 어떻게 수행하는지 가리는 행위
객체가 기능을 어떻게 수행하는지 가린다고? 왜 그게 가리는거지?
우리는 코드를 봤을 때 다 확인할 수 있는데?
도대체 무슨말일까.
이건 이전 캡슐화 게시물에 나온 메시징 패싱 방법(서로 다른 객체들이 상호작용하는 것)을 생각하면 이해하기 좋습니다.
예를 들어 치킨집 사장(Chief) 객체와 치킨을 주문하려는 사람(Customer)가 있다고 합시다.
Customer는 order, pay, pickup 메서드로 치킨을 주문하고 결제하고 받을 수 있고,
Chief는 orderChicken, cookChicken, giveChicken 메서드로 치킨을 주문받고 만들고 줄 수 있습니다.
그럼 Chief 객체는 다음과 같습니다.
public class Chief {
// 주방장이 치킨을 요리하는 과정을 추상화한 메서드
public static void cookChicken() {
heatOil(); // 기름을 넣고
preheatOil(); // 기름을 예열하고
prepareChicken(); // 닭을 손질하고 염지하고
makeBatter(); // 튀김가루로 튀김옷 반죽을 만들고
coatChickenWithBatter(); // 닭에 튀김 반죽을 묻히고
fryChicken(); // 기름에 넣어 튀기고
applySauce(); // 소스를 바르고
packInBox(); // 포장 박스에 넣는다.
}
private static void heatOil() {
System.out.println("기름을 넣고");
}
private static void preheatOil() {
System.out.println("기름을 예열하고");
}
private static void prepareChicken() {
System.out.println("닭을 손질하고 염지하고");
}
private static void makeBatter() {
System.out.println("튀김가루로 튀김옷 반죽을 만들고");
}
private static void coatChickenWithBatter() {
System.out.println("닭에 튀김 반죽을 묻히고");
}
private static void fryChicken() {
System.out.println("기름에 넣어 튀기고");
}
private static void applySauce() {
System.out.println("소스를 바르고");
}
private static void packInBox() {
System.out.println("포장 박스에 넣는다.");
}
// 주문을 처리하는 메서드
public static void orderChicken() {
System.out.println("치킨을 주문받았습니다.");
System.out.println("요리중입니다...");
cookChicken(); // 치킨을 요리하는 과정을 호출
giveChicken();
}
public static void giveChicken() {
System.out.println("치킨이 완성되었습니다. 맛있게 드세요!");
}
}
그리고 Customer 객체와 주문하는 과정을 다음과 같다고 해봅시다.
public class Customer {
// 치킨 주문 메서드
public void order(Chief chief) {
System.out.println("주문이 접수되었습니다.");
chief.cookChicken(); // 주방장에게 치킨 요리를 요청
}
// 결제 메서드
public void pay() {
System.out.println("결제가 완료되었습니다.");
}
// 수령 메서드
public void pickup() {
System.out.println("치킨을 수령했습니다. 맛있게 드세요!");
}
// 메인 메서드
public static void main(String[] args) {
Customer customer = new Customer(); // 고객 객체 생성
Chief chief = new Chief(); // 주방장 객체 생성
// 고객이 주문하고, 결제하고, 수령하는 과정
customer.order(chief); // 주문 시 주방 객체를 전달
customer.pay();
customer.pickup();
}
}
물론 주문이 아니라 pay하는 순간 주방 객체에게 요청해야겠지만 우선 order 메서드랑 상호작용을 한다고 합시다.
그럼 Customer 객체 입장에서 Chief 객체의 cookChicken 메서드가 정확히 어떻게 수행하는지 안보입니다.
단순히 Chief 객체를 생성하고 cookChicken 메서드로 메시징패싱을 하면 되니까요.
public void order(Chief chief) {
System.out.println("주문이 접수되었습니다.");
chief.cookChicken(); // 주방장에게 치킨 요리를 요청
}
객체의 공통적인 속성과 기능을 추출하여 정의하는 것
이건 이해하기 쉽죠.
많은 치킨 메뉴들 중 (지코바 양념치킨, 뿌링클 치킨, 양념 치킨, 후라이드 치킨, 누릉지 치즈 치킨, 간장 치킨, 마늘 치킨)
가장 공통적인 속성 및 기능은 무엇일까요?
바로 치킨이죠. 닭으로 요리했다는 점이 제일 큰 상위개념. 추상화의 첫 단추입니다.
그럼 치킨에서 튀긴 치킨인지 구운 치킨인지 상세히 나누는건 구체화를 하는 겁니다.
튀긴 치킨에서 후라이드 치킨을 할지, 양념 치킨을 할지
양념 치킨에서 기본 양념 치킨을 할지 마늘 양념, 간장 양념을 할지 등 세부적으로 나눌 수 있죠.
구운 치킨에서도 마찬 가지입니다.
그냥 굽기만 할지, 안에 찰밥을 넣어서 구울 지
굽고 나서 양념을 바를지 안바를지 등 세부적으로 나눕니다.
그렇기 때문에 추상화를 하면 할수록(추상화의 첫 단추가 될수록) 객체의 세부적인 특징 사라지고 공통된 특징만 남게 됩니다.
++ 부가적으로 유투브 영상에서
C++의 아버지인 Bjarne Stroustrup께서 말씀하는 추상화도 알려줬는데 다음과 같습니다.
"act of specifying a general interface hiding implementation details"
구현 세부 정보를 숨기는 일반 인터페이스를 지정하는 행위
-> 1번 개념을 잘 이해하면 받아 들일 수 있겠네요!
뭐하러 해? 왜 필요해?
그럼 개발을 할때 이런 추상화가 왜 필요할까?
1. 개발을 빠르게 하기 위해서
2. 유연한 프로그래밍 구조를 만들기 위해서
개발을 빠르게하기 위해서 왜 추상화가 필요할까요?
개발하려는 시스템에서 필요한 객체들을 개념적으로 추상화 하며 상위 요소부터 만들어 두는게 편리합니다.
이때 상속 개념도 중요한거구요.
[앞에도 나와있는 예시입니다.]
예를 들어 우리가 치킨집을 개업하는 사장이라고 해봅시다. 그럼 치킨 메뉴를 개발하고 손님들에게 선보여야겠죠?
그럼 무슨 치킨 메뉴를 개발해야 좋을까요?
지코바 양념치킨? 후라이드 순살 치킨? 화덕 마늘맛 치킨? 간장 뼈 치킨?
지코바 양념치킨은 구워야하고 후라이드는 기름에 튀겨야합니다.
순살 치킨을 팔려면 재료를 애초에 순살로 구매해놔야하고 뼈 치킨을 팔려면 뼈 치킨을 구매해놔야합니다.
이렇게 세부적으로 메뉴를 어떻게 만들까 고민하다가는 시간이 꽤 오래 걸리겠죠?
우선 상위 개념부터 정합시다.
1. 튀긴 치킨으로 할 것인지? / 구운 치킨으로 할 것인지? (둘다 하고싶다고요? 하지만 우린 늘 한정적인 자원과 시간에서 최선의 효율을 내야하는 것이 목표기때문에 선택과 집중을 해야합니다 ^^,,)
-> 튀긴 치킨으로 결정!
그럼 어차피 만들 메뉴들 모두 튀김 치킨이니까 기름을 사고 튀김옷을 준비하면 됩니다.
그리고 나서 얼른 메뉴를 개발하고 선보일 수 있겠죠?
그럼 추상화 한것이 유연한 프로그래밍 구조랑은 무슨 상관인가요?
다음과 같은 상황이 발생한거죠.
장사가 엄청 잘되서 손님들 중 한명이 문의합니다.
"저는 뼈치킨을 싫어해요.. 순살 치킨으로도 메뉴를 만들어주세요."
어렵지 않습니다. 저는 지금 튀긴 치킨을 팔고 있고 단순히 재료를 순살로 된 치킨을 구매하면
조리 과정은 동일하니까 바로 다른 메뉴를 만들 수 있는 유연함을 갖고 있는거죠.
그 밖에도 제가 포장하는 것을 정사각형 포장에서 갑자기 직사각형 포장으로 바꿔도 손님들에게 치킨을 만들어주는 것은 달라지지 않습니다.
정리
추상화란,
1. Input 값을 넣었을 때 Output이 존재할 때, 그 사이에서 일어나는 과정을 사용자로부터 가리는 행위.
ex>
우리가 치킨집에서 치킨을 주문할때 단순히 order 메서드와 pickup 메서드를 호출해서 치킨을 주문하고 받는 상황으로 생각해봅시다.
이때 우리는 order 메서드만 간단히 호출하는데, 사실 그 order 메서드안에서는 다음과 같은 일련의 과정들이 있는거죠.
[기름을 넣고 -> 기름을 예열하고 -> 닭을 손질하고 염지하고 -> 튀김가루로 튀김옷 반죽을 만들고 -> 닭에 튀김 반죽을 묻히고 -> 기름에 넣어 튀기고 -> 소스를 바르고 -> 포장 박스에 넣는다.]
그리고 이런 일련의 과정들을 추상화 함으로써
가게들 마다 중간에 다른 과정으로 바꾸거나 생략해도
우리 입장에서는 달라지는게 아무것도 없습니다.
그저 똑같이 order 메서드를 호출해서 치킨을 주문할 수 있죠. 이게 추상화의 장점입니다.
2. 객체의 공통적인 속성과 기능을 추출하여 정의하는 것. / 하위 요소의 공통점들을 상위 요소로 추려내는 것.
ex> 양념치킨, 간장치킨, 후라이드치킨 ->치킨 -> 음식
참고자료
https://www.youtube.com/watch?v=M3zlc6jiB5o
'JAVA > 기초개념' 카테고리의 다른 글
객체 지향의 설계 원칙 SOLID 법칙 (0) | 2024.05.29 |
---|---|
[Java] 객체 지향 언어의 특징 - 다형성 (오버로딩, 오버라이딩) (0) | 2024.05.28 |
[Java] 객체 지향 언어의 특징 - 상속 (0) | 2024.05.28 |
[Java] 객체 지향 언어의 특징 - 캡슐화(Encapsulation) (0) | 2024.05.16 |