You are on page 1of 5

25장부터는 3부이며 여기서부터 객체 지향 프로그래밍 방법을 연구한다.

 2부까지는 C/C++ 언어의 문법과 절차적


프로그래밍 방법에 대해 논했었는데 이번 장부터는 클래스를 통해 객체를 프로그래밍하는 방법에 대해 다룬다. 객
체 지향이란 단순한 언어의 기능적인 확장이 아니라 완전히 새로운 프로그래밍 방법이며 절차적인 방법과는 근본
적으로 다르다.

그래서 구조적 프로그래밍 기법에 이미 익숙해져 있는 사람은 습관을 완전히 바꿀 필요가 있다고 하는데 이는 어
느 정도 사실이다. 그렇다고 해서 이미 배워 놓은 구조적 프로그래밍 기법이 완전히 쓸모 없어지는 것은 아니다. 클
래스의 멤버 함수안에서는 여전히 구조적 기법이 필요하기 때문이다. C를 공부할 때와 마찬가지로 C++도 콘솔 환
경에서 실습을 진행한다. 그래픽 환경에서 멋진 예제들을 만들어 보면 좋겠지만 문법을 배울 때는 문법만 살펴볼
수 있는 단순한 환경이 훨씬 더 효율적이다.

25-1.OOP
25-1-가.소프트웨어 위기

초기의 컴퓨터는 과학 기술용 연구 도구로 개발되었으며 극히 제한된 분야에서 복잡한 공학적 계산에만 활용되었
다. 가격도 비쌌기 때문에 일반 사무용은 물론이고 개인적인 용도로 사용하는 것은 엄두도 내지 못했다. 그러나 하
드웨어의 발전에 힘입어 가격이 저렴해지고 활발하게 보급됨에 따라 컴퓨터의 활용 분야가 점점 넓어졌다. 일반 사
무용이나 개인 업무는 물론이고 심지어 게임이나 멀티미디어 등의 놀이에도 활용되었으며 요즘은 컴퓨터가 없는
생활을 상상하기 힘든 정도가 되었다.

컴퓨터가 업무와 생활 곳곳에 활용됨에 따라 특수한 용도에 맞는 다양한 소프트웨어가 필요해졌다. 또한 하드웨어
가 빨라지고 대용량화 됨으로써 컴퓨터로 할 수 있는 일들이 많아져 소프트웨어의 기능도 과거보다 훨씬 더 복잡
해지고 만들기도 어려워졌다. 사람들은 고성능 컴퓨터의 기능을 십분 활용하여 강력하고 편리하면서 또한 예쁜 프
로그램을 쓰고 싶어한다. 즉 양적으로나 질적으로나 소프트웨어에 대한 요구가 대폭적으로 증대된 것이다.

그러나 시간과 개발 인력의 부족으로 인해 소프트웨어 공급은 수요의 증가를 따르지 못했다. 뿐만 아니라 생산된
소프트웨어도 규모가 커지고 구조가 복잡해짐에 따라 질적인 결함이 많아 신뢰성이 떨어졌다. 한 두 개의 버그는
당연히 존재하는 것으로 인식될 정도였으며 때로는 이런 버그들이 심각한 문제가 되어 어렵게 만든 소프트웨어가
폐기처분되기도 했다. 소프트웨어가 하드웨어의 발전을 따라가지 못하는 이런 현상을 소프트웨어 위기(Software 
Crisis)라고 한다.

잘 알려진 무어의 법칙에 의할 것 같으면 매 18개월마다 반도체의 트랜지스터 집적도는 2배씩 높아지고 속도도 2
배씩 빨라진다고 한다. 이 계산대로라면 10년동안 중앙 처리 장치(CPU)는 대략 100배 정도 더 빨라지는데 이 법칙
은 수십년간 기가 막히게 들어 맞았고 하드웨어의 성능은 그야말로 기하급수적으로 향상되어 왔으며 앞으로도 더
발전할 것이다. 그러나 이런 하드웨어의 눈부신 발전에 비해 소프트웨어의 발전은 더디기 그지 없었다.

소프트웨어 위기의 주요 원인 중 하나는 기존 절차식 프로그래밍 방법의 낮은 생산성이었다. 절차식 프로그래밍은


간결하고 빠른 실행 파일을 만들기는 하지만 규모가 커지면 개발뿐만 아니라 유지 보수에 한계를 드러냈다. 절차식
이란 문제를 해결하는 절차가 중심인데 현실의 문제는 아주 특수하기 때문에 해결 방법도 특수할 수밖에 없다. 코
드의 일반성이 없으므로 한 번 만든 코드가 수정없이 재사용되는 경우가 드물며 매번 현실의 문제에 맞게 처음부
터 다시 개발해야 한다. 설사 재사용된다 하더라도 기존 코드를 그대로 쓰기 보다는 필요에 따라 조금씩은 수정해
야만 했다.

그러다 보니 대규모의 소프트웨어를 만드는데 수년의 개발 기간과 과다한 인력을 소모하게 되었다. 고급 인력의 부
족은 소프트웨어의 공급 부족을 초래했고 시간의 부족은 소프트웨어의 질을 저하시켰다. 하드웨어는 이미 만들어
져 있는 트랜지스터나 IC 등을 조립하는 방식으로 개발할 수 있으며 부품의 신뢰성이 높으므로 완제품의 질도 좋을
수밖에 없다. 이에 비해 소프트웨어는 항상 처음부터 다시 개발해야 하므로 시간이 걸리고 신뢰성이 떨어진다.

file://\\76.12.86.138\Drawloop Data\Site Data\Output\fetchinist@gmail.com_25-1-1.html
<!--[if !vml]--> <!--[endif]-->

그래서 대안으로 여러 가지 개발 기법들이 제시되었는데 그 중에서 가장 탁월한 기법으로 인정받은 것이 바로 절


차가 아닌 데이터를 중심으로 개발을 진행하는 객체 지향적 프로그래밍(Object Oriented Programming) 방식이다. 문
제의 핵심인 데이터를 정의하고 데이터에 절차를 결합하여 현실의 사물을 표현할 수 있는 객체를 만든다. 그리고
이런 독립적인 객체를 조립하여 프로그램을 완성해 나가는 방식이다.

객체는 재활용성이 아주 높아서 한 번 잘 만들어 놓으면 수정없이 다른 프로젝트에도 사용할 수 있다. 심지어 직접


만든 것이 아니더라도 약간의 약속만 준수하면 어렵지 않게 가져다 쓸 수도 있고 내가 만든 객체를 다른 사람에게
제공하거나 품질만 보장된다면 팔 수도 있다. 하드웨어 부품을 조립하듯이 객체를 조립하여 대규모의 소프트웨어
를 단기간에 제작할 수 있게 된 것이다. 객체가 모든 프로젝트와 다양한 환경에서 동작할 수 있는 범용성을 갖추기
는 쉽지 않지만 일단 만들기만 하면 얼마든지 재사용할 수 있고 신뢰성도 확보된다.

객체는 완전한 부품이 되기 위해 스스로 에러를 처리하고 자신의 무결성을 지키는 기능을 가지며 객체를 사용하기
위해 꼭 알아야 하는 것만 외부로 공개한다. 그래서 개발자가 객체의 내부 구조나 동작 원리를 잘 몰라도 이 객체들
을 조립하여 고기능의 소프트웨어를 신속하게 만들 수 있다. 설사 개발자가 사소한 실수를 한다 하더라도 객체는
이런 실수로부터 스스로를 보호하기도 한다. 그래서 꼭 고급 인력이 아니더라도 조립 정도만 할 수 있는 초급 개발
자도 소프트웨어를 만들 수 있게 되었다.

전자 상가에 가면 하드웨어 부품들과 설명서가 포함되어 있는 라디오 조립 키트같은 실습용 제품들이 많이 있다. 
중학생 정도만 되면 이런 조립 키트를 사서 설명서대로 기판에 트랜지스터, 저항, 다이오드 같은 부품을 조립하고
납땝하여 라디오 정도는 얼마든지 손쉽게 만들 수 있다. 하드웨어에 대한 지식이 거의 없어도, 각 부품이 정확하게
어떤 동작을 하는지 몰라도 되므로 이 얼마나 생산적인가? 소프트웨어도 이런 식으로 상세한 것을 잘 몰라도 뚝딱
뚝딱 금방 만들 수 있다면 얼마나 좋겠는가? 이것이 바로 OOP가 필요해진 이유이다.

객체 지향 방식은 조립식이기 때문에 결과물의 성능(속도와 크기)이 맞춤형의 절차식에 비해 조금 떨어지는 단점


이 있다. 그러나 하드웨어의 발전에 힘입어 그 정도의 차이는 큰 문제가 되지 않아 무시할만하다. 현대의 개발 관건
은 프로그램의 성능보다 오히려 개발 용이성과 유지, 보수 편의성, 신뢰성이다. 인건비가 하드웨어보다 훨씬 더 비
싸고 개발 기간이 곧 비용과 직결되기 때문에 얼마나 빨리 정확한 소프트웨어를 생산하는가가 관건이며 그 해답이
바로 객체 지향 프로그래밍이다.

<!--[if !supportEmptyParas]--> <!--[endif]-->

file://\\76.12.86.138\Drawloop Data\Site Data\Output\fetchinist@gmail.com_25-1-1.html
25-1-나.OOP의 특징

본격적인 학습에 들어가기 전에 객체 지향 프로그래밍의 일반적인 특징들에 대해 먼저 정리해 보도록 하자. 학


자에 따라 이 특징들 외에 몇 가지를 더 추가하기도 하며 각 특징의 범주가 조금씩 달라지는 경우도 있다. 심지
어 객체 지향에 대한 정확한 정의와 범위마저도 완벽하게 합의되어 있지 않은 상태이다보니 각 특징에 대한 정
의도 조금씩 견해가 다를 수 있다. 

<!--[if !supportEmptyParas]--> <!--[endif]-->

■ 캡슐화(Encapsulation) : 표현하고자 하는 자료(Data)와 동작(Function)을 하나의 단위로 묶는 것이며 이렇


게 묶어 놓은 것을 객체(Object)라고 한다. 대상의 특징을 나타내는 데이터와 이 데이터를 관리하는 함수가
항상 하나의 묶음으로 사용되므로 객체는 스스로 독립적이며 프로그램의 부품으로 활용될 수 있다. 그래서
객체를 소프트웨어 IC라고 부르기도 한다.

■ 정보 은폐(Information Hiding) : 객체는 자신의 상태를 기억하기 위한 속성과 속성을 관리하는 동작을 정


의한다. 이 중 외부에서 사용하는 기능만 공개하고 나머지는 숨길 수 있는데 이를 정보 은폐라고 한다. 외
부에서 객체의 상태를 마음대로 바꾸거나 허가되지 않은 동작을 요청하지 못하도록 함으로써 스스로의 안
전성을 확보하는 수단이며 정보 은폐에 의해 객체는 더욱 견고하게 캡슐화된다.

■ 추상화(Abstraction) : 현실의 사물을 객체로 표현하기 위해서는 이 사물이 어떤 특징을 가지며 어떤 동작


이 가능한지를 조사해야 하는데 이를 데이터 모델링이라고 한다. 모델링의 결과 필요한 자료와 동작의 목
록이 작성되면 이들을 캡슐화하여 객체로 정의한다. 그리고 외부에서 사용해야 하는 기능은 공개하고 제한
해야 하는 기능은 숨긴다. 추상화란 객체의 효율적이고도 안전한 사용을 위해 인터페이스를 설계하는 것이
며 캡슐화와 정보 은폐에 의해 구현된다. 추상화에 의해 외부에서는 객체의 인터페이스만 볼 수 있으며 내
부 구현은 볼 수 없다. 그래서 사용 방법이 간단 명료하고 외부의 조작에 대해 안전해지며 객체는 추상적인
인터페이스를 유지하는 한도내에서 숨겨진 내부 구현을 마음대로 수정할 수 있어 기능 개선이 쉬워진다. 
개념화라고도 한다.

■ 상속(Inheritance) : 상속은 이미 만들어진 클래스를 파생시켜 새로운 클래스를 정의하는 기법이다. 파생된


클래스는 기존 클래스의 모든 속성과 동작을 물려받으며 여기에 더 필요한 기능을 추가하거나 필요없는
기능을 제거 또는 변경할 수 있다. 객체를 아무리 추상적으로 잘 정의해 놓았다 하더라도 현실의 문제는 특
수하기 때문에 모든 경우에 일반적으로 적용되지는 않는다. 이럴 때는 객체를 상속받아 원하는 부분만 수
정할 수 있으며 기존 객체를 최대한 재활용함으로써 시간과 노력을 절약할 수 있다.

■ 다형성(Polymorphism) : 똑같은 호출이라도 상황에 따라, 호출하는 객체에 따라 다른 동작을 할 수 있는


능력을 다형성이라고 한다. 실제 내부 구현은 다르더라도 개념적으로 동일한 동작을 하는 함수를 하나의
인터페이스로 호출할 수 있으므로 객체들을 사용하는 코드를 일관되게 유지할 수 있다. 다형성은 동적 바
인딩을 하는 가상 함수에 의해 구현된다.

<!--[if !supportEmptyParas]--> <!--[endif]-->

OOP의 특성에 대해 요약적으로 설명했는데 이 설명을 읽고 당장 OOP의 본질을 파악하는 것은 쉽지 않을 것이


다. OOP의 이런 주요 특성들은 객체 지향을 논할 때 으례히 첫 부분에 나오는 설명들이다. 그러나 이 특징들을
다 이해하고 느끼려면 객체 지향 전체를 다 경험해 봐야 할 정도로 어려운 내용이기도 하다. 앞으로 구체적인
예제를 곁들인 설명을 읽고 또 직접 실습을 진행하다 보면 차츰 의미를 이해하게 될 것이다. 

이 책은 OOP의 여러 특징들을 설명하기 위해 각 특징에 대해 1~2개의 장을 할애하고 있다. 한 개념을 설명하


고 이해하는데 수십 페이지를 읽고 실습해 봐야 할 정도로 어려운 개념이라는 뜻이다. 이 특징들을 간단하게
한국말로 번역해 보면 다음과 같이 정리할 수 있다.

<!--[if !supportEmptyParas]--> <!--[endif]-->

특징 간단한 설명

file://\\76.12.86.138\Drawloop Data\Site Data\Output\fetchinist@gmail.com_25-1-2.html
캡슐화 묶는다
정보 은폐 숨긴다
추상화 표현한다
상속 재사용한다
다형성 상황에 따라 달라진다.

<!--[if !supportEmptyParas]--> <!--[endif]-->

물론 빠른 이해를 위한 간략한 비유일 뿐이므로 정확한 정의는 아니며 핵심적인 내용만 간추려 정리한 것이다. 
특히 다형성은 한 단어로 설명하기 참 어려운 개념이다.

<!--[if !supportEmptyParas]--> <!--[endif]-->

file://\\76.12.86.138\Drawloop Data\Site Data\Output\fetchinist@gmail.com_25-1-2.html

You might also like