들어가면서
지난 여름방학 H사에서 인턴 했을 때 일입니다. 인턴 과제로 C#으로 윈도우 프로그래밍 과제를 주셨습니다. 요구사항을 해결하기 위한 최적화 알고리즘은 고안해냈습니다. 그런데 마음속에 드는 생각이, 내가 두 달 뒤에 인턴십이 끝나더라도 누군가 이 코드를 봤을 때 명확하게 이해하고, 새로운 기능을 확장가능하게 편리하게 만들어야겠다는 생각이 들었습니다. 그러기 위해서 잘 설계해야 한다는 말을 어딘가에서 들었고, 클래스를 잘 짜라는 말처럼 들리는 잘 설계라는 말은 주니어 개발자로서 참 어려운 일이었습니다.
대체 거대한 프로그램을 어떻게 나누고
미래에 소의 등에 날개가 달릴것 까지 고려해서 확장 가능하게 개발하고
다른 사람이 소의 해부도를 보면 한 번에 이해되게 코드를 짜라니...
꼭 객체지향에 대해서 정리하고 싶었습니다. 주니어 개발자로서 어디서 주워들은 객체지향 이야기를 쏟아내기보다는 몇 년 전에 학교 도서관에서 읽어봐야지 생각만 했던 '스프링 입문을 위한 자바 객체 지향의 원리와 이해'을 바탕으로 객체지향 이야기를 하려고 합니다. 중간 마다 메모리에 대한 설명과 책의 구성과 표현이 다듬어 지지 않아 산만한 감이 없지 않으나 객체 지향에 대해서 한 번 정리하고 넘어가기에 괜찮은 책이라 글로 남겨봅니다.
객체 지향의 등장
프로그래밍은 개발자에게 친화적으로 발전해 왔습니다. 어셈블리어부터 시작해서 C 그리고 자바로 발전해온 과정을 보았을 때, 로우 레벨의 언어에서 인간이 이해하기 쉬운 하이 레벨 언어로 발전해왔습니다.
객체지향은 현실 세계처럼 프로그래밍하기 위해서 탄생한 개념입니다. 기존의 구조적 프로그래밍 언어에서 가장 중요한 것은 함수였습니다. 함수는 코드를 논리적인 단위로 구분하고 나누겠다는 뜻입니다. 몇천, 몇만 라인의 명령어를 논리적인 단위로 나누어 블록화해서 작성하자는 것입니다. 이러한 논리적 블록의 단위를 함수라고 합니다.
이 글을 읽는 여러분은 잠시 글 읽는 것을 멈추시고 눈을 감고 아무 상상해보세요. 오늘 저녁으로 먹은 사과가 생각나시나요? 고요한 방 안에서 시침 소리가 들리시나요? 우리가 24시간 동안 사물을 보고, 눈을 감아도 사물이 머릿속에 맴돌 것입니다. 사물을 앞으로 객체, 영어로 Object라고 할 것입니다. 객체 지향으로 우리가 현실세계를 인지하는 방식대로 프로그래밍 할 것입니다. 그래서 객체지향은 직관적입니다.
객체 지향을 이해하기 전에 다음과 같은 전제가 깔립니다.
- [1] 세상에 존재하는 모든 것은 사물, 즉 객체이다.
- [2] 각각의 사물은 고유하다.
- [3] 사물은 속성을 갖는다.
- [4] 사물은 행위를 한다.
어렵게 생각할 것 없이 하나의 예시를 들면 됩니다. 김철수는 [1]사물로써 [2]고유한 사람입니다. [3] 키, 몸무게라는 속성이 있습니다. [4] 보기, 듣기, 걷기 등등 행위를 할 수 있습니다.
객체 지향의 4대 특성 - 캡상추다!
캡상추다!를 외치며 객체 지향의 4대 특성을 암기해봅시다.
- 캡: 캡슐화(Encapsulation): 정보은닉
- 상: 상속(Inheritance): 재사용
- 추: 추상화(Abstraction): 모델링
- 다: 다형성(Polymorphism): 사용편의성
(면접때 많이 나옵니다...)
클래스 vs 객체 == 붕어빵틀 vs 붕어빵 ???
대부분의 JAVA 책에서는 클래스와 객체의 관계를 붕어빵틀과 붕어빵의 관계로 설명합니다. 저 또한 JAVA를 공부할 때 읽은 기본서에서 붕어빵틀에 클래스를 비유해서 설명하였습니다.
클래스 객체명 = new 클래스()
위와 같은 코드가
붕어빵틀 붕어빵 = new 붕어빵틀()
비유를 활용해서 보면 위와 같이 쓸 수 있을 것입니다. 그런데 금형 기계와 붕어빵틀이 클래스와 객체 관계가 아니듯 붕어빵과 붕어빵도 클래스와 객체의 관계가아닙니다. 정확하게 표현하면 붕어빵틀은 붕어빵을 만드는 팩터리입니다.(디자인 패턴 참고)
- 펭수는 클래스일까요? 객체일까요?
- 펭귄은 클래스일까요? 객체일까요?
- 김보안은 클래스일까요? 객체일까요?
- 사람은 클래스일까요? 객체일까요?
클래스는 분류에 대한 기념이지 실체가 아닙니다. 반대로 객체는 실체입니다. 펭귄이라는 분류(class)안에 펭수라는 객체(object)가 있는 것입니다.
캡슐화(Encapsulation): 정보은닉
외부의 잘못된 사용으로 객체가 손상되지 않도록 합니다. 이를 통해 변화에 유연하게 대응합니다.
(책에는 메모리관점으로 복잡하게 설명되어 있습니다. 궁금하신 분은 책 참고해주세요. 메모리 관점은 한 번에 정리해서 올려보겠습니다.)
상속: 재사용 + 확장
객체지향의 상속에 대한 잘못된 예 - 계층도 / 조직도
상속이라는 단어 때문에 많은 오해를 낳습니다. 객체 지향의 상속은 아래 그림처럼 재사용과 확장의 의미로 이해하는 것이 맞습니다. 즉 분류도로 이해해야 합니다.
객체지향의 상속에 대한 올바른 예 - 분류도
위 그림은 상속 관계가 아닙니다. 동물은 포유류의 부모가 아닙니다. 고래 또한 부모가 포유류라고 하는 것은 어색한 표현입니다. 객체 지향에서의 상속은 상위 클래스의 특성을 하위 클래스에서 상속하고 거기에 더해 필요한 특성을 추가, 즉 확장해서 사용할 수 있다는 의미입니다.
상속 관계에는 '하위 클래스는 상위 클래스이다.' (이는 LSP-라스코프 치환 원칙과 통합니다.)
다형성(Polymorphism): 사용 편의성
객체 지향에서 다형성은 오버라이딩(Overriding)과 오버로딩(Overloading)이라고 할 수 있습니다.
- 오버라이딩: 같은 메서드 이름, 같은 인자 목록으로 상위 클래스의 메서드를 정의
- 오버로딩: 같은 메서드 이름, 다른 인자 목록으로 다수의 메서드를 중복 정의
암기를 위해서(대학생 시절 자바 시험에 나온게 기억납니다..) 오버라이딩, 라이딩 단어에 주목해 봅시다. 오토바이에 올라탄다고 생각해 보세요. 하늘에서 보면 한 명의 사람만 보이겠죠? 오버로딩, 로딩 단어에 주목해 봅시다. 짐을 옆으로 쌓을 것입니다. 하늘에서 보면 많은 물건이 적재되어 있는 것을 볼 수 있습니다.
다중상속과 자바
다중 상속의 문제점
사람은 수영할 수 있고 물고기도 수영할 수 있다. 그렇다면 사람의 속성, 물고기의 속성을 가지고 있는 인어는 어떻게 수영해야할까요? 물고기처럼 꼬리를 사용해서 헤엄쳐야 할까요? 사람처럼 팔과 다리를 저어서 헤엄쳐야 할까요? 다중 상속을 하게되면 이러한 모호성이 생깁니다. 이것을 다이아몬드 문제 라고 합니다.
이렇게 자바에서는 C++에는 없는 인터페이스를 도입해서 상속이 갖는 장점만 갖게 됩니다.
추상화: 모델링
추상화란 구체적인 것을 분해해서 관심 영역에 대해서만 특성을 가지고 재조합 하는 것.
이를 IT 용어로 풀어쓰면 다음과 같습니다.
추상화란 구체적인 것을 분해해서 관심 영역(애플리케이션의 경계, Application Boundary)에 있는 특성만 가지고 재조합 하는 것 = 모델링
병원 애플리케이션을 만들 때 사람은 환자의 관점으로 바라볼 것입니다. 클래스 모델링을 할 때 시력, 키, 몸무게, 혈액형, 나이 등, 먹다(), 자다(), 운동하다() 등으로 할 수 있습니다.
은행 애플리케이션을 만들 때 사람은 고객 관점으로 바라볼 것입니다. 클래스 모델링을 할 때 키, 혈액형은 필요가 없으며, 나이, 직접, 연봉, 신용등급, 입금하다(), 출금하다(), 대출하다() 등으로 할 수 있습니다.
모델링은 실제 사물을 정확하게 복제하는 것이 아니라 목적에 맞게 관심 있는 특성만을 추출해서 표현하는 것입니다. 즉, 모델은 추상화를 통해서 실제 사물을 단순하게 묘사하는 것입니다.
클래스 객체_참조변수 = new 클래스();
클래스 | 객체_참조변수 | = | new | 클래스 | () |
---|---|---|---|---|---|
객체_참조_변수의_자료형 | 생성된 객체를 참조 할 수 있는 변수 | 할당문 | 새로운 | 만들고자 하는 객체의 분류 | 매서드 |
* 새로운 객체를 하나 생성해 그 객체의 주소값을 객체 참조 변수에 할당 |
이미지 출처
광고 꽝고~
'Computer Science > Java-Spring' 카테고리의 다른 글
[로켓 학습] 스프링부트 CRUD REST API (JPA, MySQL, Gradle) (31) | 2021.05.19 |
---|---|
[스프링 시큐리티] 디버깅 로그 출력 방법 (0) | 2021.04.25 |
📘 명저로 다시보는 자바와 메모리 이야기 2편 (0) | 2020.03.24 |
📘명저로 다시보는 자바와 메모리 이야기 1편 (0) | 2020.03.23 |
이클립스에서 Java와 Github저장소 연결하기 (0) | 2017.08.14 |