1. nonezerok@gamil.com
http://cespc1.kumoh.ac.kr/~nonezero
본 문서의 무단 복제를 불허합니다.
객체지향 프로그래밍이란: 객체위주로
이 문서는 객체지향 프로그래밍의 개념을 이해하는데 도움을 주고자 작성되었습니다. 객체
지향 프로그래밍이란? 질문에서 시작하여 개념이 어떻게 프로그래밍 언어의 문법으로 만들
어 지는지를, 객체지향의 객체와 C++의 클래스를 연결 지워봅니다. 이 과정에서 추상화,
캡슐화, 정보은닉의 의미를 자연스럽게 이해할 수 있습니다.
객체지향 프로그래밍이란?
이 질문에 쉽게 대답할 수 있습니까? 들어는 봤어도 막상 설명하라고 하면 매우 난감합니다.
그러나, 너무 어렵게 생각하지 않아도 됩니다. 사실 답변은 질문에 이미 들어있기 때문이다.
객체지향 프로그래밍은 객체를 기반으로 한 프로그래밍입니다.
당연한 대답입니다. 이 대답을 통해 객체에 대한 의문을 가지지 않을 수 없습니다.
객체란 무엇일까요?
객체에 대한 다양한 설명방식이 있겠지만, 여기서는 프로그래밍 언어의 문법적 측면에서 살
펴보겠습니다. 저의 대답은 이렇습니다.
객체란 데이터 추상화의 산물이다.
이제 다시 바턴은 객체에서 추상화로 넘겨졌습니다. 추상화에 대한 설명에 앞서, 객체지향
방법론이 나타나게 된 배경을 먼저 알아봅시다. 1970년대 하드웨어의 발전속도는 급격하게
이루어지는데 반해, 소프트웨어 개발속도는 이에 미치지 못하였습니다. 이를 소프트웨어 위
기론이라고 합니다. 그 당시 프로그래밍 개발방법의 주류는 구조적 프로그래밍이었습니다.
구조적 프로그래밍은 여러분이 이미 알다시피 모듈화에 기반을 둔 프로그래밍입니다. 이 모
듈화를 C언어에서는 함수라는 문법으로 도입했습니다. C언어의 예들 통해 문제점을 살펴보
겠습니다. 다음 코드를 봅시다.
#include <stdio.h>
2. int data; // 전역변수
int func0001( );
int func0002( );
( … 중략 … )
int func1000( );
보시다시피 data는 전역변수입니다. 이 변수를 사용하는 함수는 func0001() 뿐이라고 합시
다. 여러분의 동료가 이 소스코드를 여러분에게 주면서 func0001() 이상한 것 같으니 고쳐
달라고 합니다. 그는 전역변수 data가 이 함수에서만 사용된다고 얘기하는 것도 잊어버렸습
니다. 아마도 여러분이 이러한 부탁을 받았다면 func001() 뿐만 아니라 1000개의 모든 함
수를 살펴볼 것입니다. 설사 그가 전역변수 data는 func001()에서만 사용된다고 말해 주었
다고 하더라도 말입니다. 이것은 data가 전역변수이기 때문에 시작된 문제입니다. 이처럼
전역변수가 사용됨으로써 하나의 함수만 살펴보면 될 것을 1000개의 함수를 모두 살펴봐야
하는 문제를 야기합니다. 이 문제를 해결하기 위한 방법으로 당시 개발자들은 다음과 같은
목표를 세웁니다.
어떤 변수와 그 변수를 사용하는 함수를 하나로 묶어서 타 함수에서는 이 변수를 사용할 수
없게끔 하자.
변수와 함수를 묶기 위해서 C언어는 struct 키워드를 확장했습니다. 원래 struct는 변수만
묶을 수 있습니다.
#include <stdio.h>
struct {
int data;
int func0001( );
};
int func0002( );
( … 중략 … )
int func1000( );
이렇게 묶여 있을 때 다른 함수에서 다음과 같은 코드를 작성했다고 합시다.
int func1000( )
{
A a;
a.data = 100; // 문법적으로 올바르다.
}
구조체의 멤버변수를 사용하기 위해서는 도트(.) 연산자를 사용합니다. 위 코드는 아무 문제
없이 컴파일이 됩니다. func1000()은 구조체의 사용방법에 따라 data라는 변수에 접근할 수
있습니다. 그러나, 이것은 그들이 정했던 목표를 달성하지 못합니다. 변수와 함수를 묶기만
했지, 여전히 타 함수에서 접근이 가능하기 때문입니다. 이 문제를 해결하기 위해서는 추가
3. 적인 문법이 제정되어야 합니다. 실제로 다음과 같이 private 이라는 키워드가 제정되었습
니다.
struct A {
priavte: // 아래 변수와 함수는 외부에서 사용할 수 없도록 지정
int data;
int func0001( );
};
int func1000( )
{
A a;
a.data = 100; // 여기서 문법에러 발생
}
이제는 타 함수에서 data변수에 접근할 때 문법적으로 에러를 발생합니다. 이 참에 struct
와 private 키워드를 대체할 수 있는 하나의 키워드를 제정했습니다. 그것이 바로 class 입
니다. 이제 위 코드는 다음과 같이 변경할 수 있습니다.
class A {
int data;
int func0001( );
};
int func1000( )
{
A a;
a.data = 100; // 여기서 문법에러 발생
}
이와 같이, 데이터와 그 데이터를 사용하는 함수를 하나로 묶고, 다시 외부에서 사용할 수
없게끔 해주는 과정을 데이터 추상화라고 합니다. 객체지향에서 사용되는 용어로 다시 설명
하면 다음과 같습니다.
데이터 추상화는 변수와 그 변수를 사용하는 함수를 캡슐화(encapsulation)하고, 그들을 외
부에서 사용하지 못하게 정보은닉(information hiding)하는 과정이다.
이러한 데이터 추상화가 객체지향의 가장 핵심 개념입니다. 질문 한가지 더 하겠습니다. 이
개념을 C++에서 구현하기 위해 만든 키워드가 무엇이었습니까?
C++에서 데이터 추상화를 구현하기 위해 만든 키워드는 class 입니다.
클래스는 구조체입니다. 구조체를 정의하면 메모리 할당이 일어나지 않듯이, 클래스를 정의
해도 메모리 할당은 일어나지 않습니다. 실제로 메모리 할당을 하기 위해선 선언을 해야 합
니다. 다음과 같이 선언을 했을 때 메모리가 할당되어 클래스가 구체화됩니다.
4. A a;
이렇게 클래스로부터 변수를 선언하는 것을 개체화 한다고 말합니다. 이렇게 개체화한 것을
다시 객체라고 합니다. 결국, 다음과 같이 얘기할 수 있습니다. 두 번째 대답했던 객체는 추
상화의 산물이다 라고 얘기하는 것이 비약은 아니었습니다. 통상 객체와 개체는 문맥에 따
라 혼용됩니다. 심지어는 클래스와도 혼용되기도 합니다. 사실 클래스는 객체를 찍어내는
틀인 셈인데 말이죠.
개념이해의 중요성에 대하여
객체지향의 개념에서 출발하면 C++에 적용된 문법을 보다 쉽게 이해할 수 있습니다. 대부
분의 문법은 추상화로부터 출발합니다. 예들 들어, 생성자가 그렇습니다. 이것들은 여러분의
상상에 맡기겠습니다. 개념을 무시하면 안됩니다. 개념으로부터 출발하면 더 쉽게 새로운
기술을 이해할 수 있습니다.
객체지향 개발 방법론의 다음 단계가 일명 CBD(Component Based Development)라는 개
발 방법론입니다. 이 방법론은 당연히 객체지향에 기반을 두고 있습니다. 마이크로 소프트
에서 이를 구체화한 기술이 COM입니다. 많은 사람들이 COM을 어려워합니다. 이들 중 대
부분은 개념을 무시한 채 예제만 보려고 하기 때문입니다. Example-Oriented되어 사용방법
만 익히고 개념을 터득하려 하지 않는다면 급변하는 기술을 따라잡을 수 없습니다. 너무 많
은 기술을 쫓아가려 하기 보단 우리 선인들이 같은 책을 1000번을 읽고 이치를 터득하였듯
이, 개념이해에 노력을 기울이길 바랍니다.