(!)객체지향
최근들어 객체지향이라는 말이 빈번하게 등장하고 있으며 그 중요성이 점차 커지고 있다.
여기서는 객체와클래스의 의미를 분석하고 클래스의 특징들을 고찰 해보겠습니다.
1) 객체
객체란 우리가 주변에서 흔히 볼 수 있는 물체 또는 생각할 수 있는 그 어떤 것을 말하며,
객체지향 프로그래밍이란 객체를 중심으로 하여 프로그램을 작성하는 방법을 말한다.
기존의 C나 Pascal과 같은 언어는 절차를 중심으로 해서 만들어진 언어인 반면
C++나 Java와 같은 언어는 절차보다는 문제의 대상들 즉 객체를 중심으로
프로그램을 만드는 언어라고 볼 수 있다.
2)객체의 구성
-객체의 상태:현재 객체가 어떤 상황에 있으며 객체의 특성은 어떤 것이 있는지에 대한 상태가 들어있다.
볼펜을 예로 들어서 설명하면 볼펜의 상표, 남은 잉크의 양, 잉크의 색깔 등이 객체의 상태가 될 것이다. 객체지향 언어에서는 이것을 멤버 변수 ,속성 등으로 표현한다.
- 객체가 할 수 있는 일 : 객체가 할 수 있는 일들을 표시할 수 있다.
위의 예처럼 볼펜을 중심으로 살펴보면 쓰기라는 일을 할 수 있는 기능이 있다고
볼 수 있다. 객체지향에서는 이러한 것을 멤버 함수 또는 메소드 등으로 표현한다.
3)클래스의 특징
-캡슐화
외부로 알릴 필요가 없는 클래스 내부에 있는 자료를 감추어서 하나의 캡슐로 만든다는 의미를 가지고 있다.
-다형성
다형성이란 클래스 외부에서는 하나의 작업으로 생각하게 되고 내부에서는 각기
다른 방법으로 구현이 되는 것을 말한다.
결과는 같지만 내부의 움직이는 방법이 서로 다르게 구현되는 것을 다형성이라고 한다.
객체지향에서는 이러한 특성을 함수의 다중 선언으로 구현한다.
같은 멤버 함수의 이름을 가지고 있지만 호출할 때 전해 주는 인수의 개수나
타입의 차이로 구분하는 것을 말한다.
-상속성
상속성은 말 그대로 클래스가 멤버 함수나 멤버 변수 등 자신의 모든 특성을 기준으로 자신의 자식 클래스를 작성 할 수 있는 특성을 말한다.
=====================================
1. 객체 지향이란?
객체지향이란 용어는 Simula 67 프로그래밍 언어에서 객체(object)라는 개념을 사용한데서 유래했다. 객체는시스템을 구성하는 실체(entity)로서 각 객체는 한 구성원의 특성과 상태변화를 구현하는 기본 단위라 할 수 있다.객체는 소프트웨어를 구성하고 실제 소프트웨어를 작동시키는 실체들즉, 논리와 데이타가 분리되어 있는 기존의구조적 사고에서 과감히 탈피하여 논리와 데이타가 결합된 객체들이 시스템을 이룬다는 것이다. 객체지향이란소프트웨어를 자료구조(data structure)와 행위(behavior)가 결합된 객체들의 구조화 된 집합으로 보는 시각이다. 소프트웨어를 구현하는 방법이라기 보다는 실세계의 문제를 보는 개념이다.
2. 객체 지향 프로그램 방법의 변화
1.1. 1960년대에 Simula
1.1.1. Algol60을 확장하여 실세계를 시뮬레이션 하는 목적을 가짐
⇩
1.2. 1970년대 Simula 67
1.2.1. 추상 자료형이고 다른 하나는 객체 패러다임 자체의 개발
⇩
1.3. Smaltalk-80
1.3.1. 객체 패러다임 구현
⇩
1.4. 1980년대 중반 객체 프로그래밍은 프로그래밍 언어의 용례로서만이 아닌 프로그램 설계의 방법론으로 확장
3. 객체 지향 프로그램의 장ㆍ단점
3-1. 객체 지향 프로그래밍의 장점
(1) 생산성 향상(Improvement of productivity) :객체지향 기술에서 추구하는 궁극적인 목표는 잘 설계된 클래스들, 즉 하드웨어의 IC처럼 소프트웨어 라이브러리(library)를 재사용하는 것이다. 종전의 개발 방법과는 달리 객체(object)는 IC처럼 독립적이어서 이를 재사용함으로 생산성tivity)이 증가하게 된다. 어느 한 보고서에 의하면 객체지향 소프트웨어 개발에 기존 클래스의 재사용률이 80%에 이른다고 한다.
(2) 자연적인 모델링(Natural modeling)객체, 클래스, 속성 상속 및 다형성(polymorphism) 등은 우리의 일상생활에서 보통 사람들이 대하고 생각하는 방식을 그대로 프로그램 언어로 표현할 수 있게 해준다.
(3) 재사용(Reuse)객체지향 프로그래밍은 코드의 재사용을 극대화한다.한 프로그램 내에서 subclass들이 superclass의 속성을 표현한 코드를 재사용하며, 새로운 프로그램 개발시 기존 프로그램이 갖고 있는 클래스 상속 구조에서 많은 클래스들을 소프트웨어 IC로 재사용할 수 있다.
(4) 유지보수(maintenance)의 용이성객체지향 프로그램은 기존의 기능을 수정하거나 새로운 기능을 추가하기가 용이하다. 기존 기능을 수정시 함수를 새롭게 바꾸더라도 캡슐화와 그 함수의 세부정보가 은폐되어 있어 주변에 미치는 영향을 최소화 한다. 새로운 객체의 종류를 추가시에는 속성 상속을 통하여 기존의 기능을 활용하고 존재하지 않은 새로운 속성만 추가하면 되므로, 매우 경제적이다.
(5) 이외에도 점진적(incremantal) 프로그램 개발의 용이성, 요구사항) 변화에 대해 안정된 프로그램 구조 등의 장점들을 들수 있다.3-2. 객체 지향 프로그램밍의 단점객체지향 프로그램의 유일한 단점으로 실행시의 속도(runtime efficiency)가 떨어진다고 알려져 왔다. Smalltalk이나 C++ 등의 객체지향 언어로 만들어진 응용 프로그램은 Fortran이나 C 등의 재래식 언어로 만들어진 프로그램에 비해 실행 속도가 늦다는 말을 흔히 듣게 된다. 이것은 유연성(flexibiblity)와 효율성(efficiency)의 trade-off 관계에 기인한다.객체지향 프로그램은 객체라는 단위를 컴퓨터의 기억장치에 어떤 형태로든 표현해야 하고, 객체간의 정보교환이 모두 메시지 교환을 통해 일어나므로 재래식 프로그램보다 실행시스템에 많은 부하(overhead)가 생기게 된다. 하지만, 이러한 운용시 호율성 문제는 효율성이 뛰어난 새로운 언어들의 탄생으로 이제 거의 문제가 되지 않는다. 특히, 기존의 언어 C나 Pascal 등을 확장한 C++나 Object Pascal 등은 기존 언어의 효율성과 객체지향의 장점들을 모두 제공한다.
4. 객체 지향 분석기법
(1) 객체 모델링 : 정보 모델링이라고도 부르며 System에서 요구되는 객체를 찾아내어 객체들의 특성과 객체들 사이의 관계를 규명한다.
(2) 동적 모델링 : 객체 모델링에서 규명된 객체들의 행위와 객체들의 상태를 포함하는 라이프, 사이클을 보여준다.
(3) 기능 모델링 : 객체 모델링에어 규명된 객체와 동적 모델링에서 밝혀진 각 객체의 형태 변화에서 새로운 상태로 들어갔을 때 수행되는 동작들을 기술하는데 사용된다.
=========================================
▣ 객체지향 프로그램이란?
그 의미를 알아 보기위해 객체(Object)에 대해 알아보자.
객체(Object)란 실세계에 존재하는 모든 사물을 일컫는 말이다.지금 현재 보면 타이핑을 하고 있는 나도 객체라고 할수 있고, 컴퓨터, 의, 책상, 저 멀리 자동차, 자판기 등등..이런 우리 주의에서 볼 수 있는 모든 것들을 객체(Object)라 한다.
그럼 객체지향 이란 무엇을 말하는 건가.객체 지향이란 이런 실세계에 존재하는 객체를 컴퓨터 상에서 표현하는 것을 말하고 객체 지향을 해서 작성한 것을 객체 지향 프로그램이라고 한다.
▣ 객체지향 프로그램의 세단계
- 실세계(Real World): 객체가 존재하는 실세계를 의미.
- 모델링 : 실세계에 존재하는 객체에 대해 객체가 어떻게 구성되었는지 분석하는 단계.
- 컴퓨팅 세계(Computing or Software World): 두 번째 단계에서 추상화하여 생성한 상태에 대해 프로그래밍 을 하기 위해 변수로 나타내고, 행동에 대해서는 메소드(또는 함수)로 표현하게 하는 단계.
▣ 객체지향 프로그램의 특징
- 캡슐화(Encapsulation):
일반적으로 캡슐화는 어떤 하나를 다른 것에 포함시킴으로써, 포함된 것이 외부에서 보이지 않도록 하는 것이다.쉽게 말해서 숨길것은 숨기고 보여줄 것은 보여준다는 뜻이다.예를 들어 내가 여행사에 가서 비행기표를 예약한다고 하자. 그럼 나는 여행사(객체)에가서 창구 여직원(메서드)에게 돈(매개변수)을 주면서 예약을 하고 비행기표(리턴값)를 받을 것이다. 여기서 숨겨진 것은 다른 비행기 좌석이 얼마나 남았는지, 총 비행기표 수입 금액이 얼마인지 등은 내부처리이므로 나는 알 수가 없는것이다. 이렇듯 캡슐화는 보안, 외부 클래스와의 접근 제한의 이유로 객체지향 프로그램에 사용된다.
이런 이유로캡슐화는 정보 은닉화(Information Hiding)을 지원해 준다. 정보 은닉화(Information Hiding)란 객체에 대한 외부의 접근을 허락하거나 금지하는 기능을 의미한다. 위 예에서는 비행기표를 예매하는 시스템에 접근을 금지하는 것은 '나'이고 허락되는 것은 '직원'이 된다.
자바에서 캡슐화는 메서드와 클래스를 중괄호({})로 묶음으로서 사용이 되며, 정보 은닉화는 접근 제한자 키워드(public, protected, private )로 제공된다.
- 다형성(Polymorphism)
다형성은 같은 객체이지만 조건에 따라서 다르게 작용한다는 뜻이다. 예를 들어 계산기(객체)에서 합계를 구한다(메서드)고 하자. 입력란에 정수를 적거나, 소수, 분수(조건=매개변수)를 적으면 합계를 구하는 공식은 같지만 결과는 다르다는 것이다. 이는 모두 합계를 구하는 메서드를 호출하지만 넘겨주는 메세지는 다르다는 것이다.
다형성은 자바의 문법 중 오버로딩(Overloading) 개념에 사용된다. - 상속(Inheritance):
상속은 말 그대로 부모의 재산을 자식이 물려받는다는 뜻으로 자바에서는 미리 정의된 클래스를 상속받아 다른 클래스를 생성 또는 정의할 수 있다. 기존의 개발자가 미리 만들어 놓은 여러가지 개발 루틴이나 라이브러리(Library)를 사용한다는 것은 개발자 입장에서 아주 편리하고 시간과 비용을 줄일 수 있는 좋은 방법이다. 자바에서도 이런 라이브러리를 사용할 수 있는데 이를상속이라 한다. 이러한 상속은 모듈의 재사용(reuse)과 코드의 간결성을 지원해 준다.
상속의 개념은 자바의 문법 중 오버라이딩(Overriding) 개념에 사용된다.
===============================
예전에 프로그래밍이 처음 나왔을때 프로그래머가 생각나는데로 프로그램을 했습니다. 처음에는 이런 방법이 잘 먹혀들었습니다. 하지만 컴퓨터가 발전해가면서 문제가 생겼습니다. 개집을 지을때는 설계도가 필요없겠지만 아파트를 지을때 설계도 없이 지을수 없는 것 처럼 큰 소프트웨어를 주먹구구식으로 지어서는 개발에도 유지보수에도 문제가 생긴것이지요. 그래서 프로그래머들은 생산성을 높이기 위해서 논쟁을 하게 됩니다. 그 와중에 코드가 dirty하다는 말이 나오고 이에 대해서 논문이 나오게 되면서 모듈화란 이론이 생겼습니다.
모듈화는 "기능별"로 프로그램을 쪼개는 것이지요. 예를 들어 오디오라면 CD 플레이어, 앰프, 프리앰프, 데크, 튜너등이 있습니다. 이걸 한꺼번에 만드는 것은 어렵지만 CD 플레이어, 앰프, 프리엠프, 데크, 튜너를 하나씩 만들어서 붙이면 분명히 원하는 기능도 사용할수 있고 만들기도 편리합니다. 이러한 방법이 모듈화이지요.
여기서 더 나아가서 개체란 말이 나오게 됩니다. (object라는 용어를 객체로 번역할껀지 개체로 번역할껀지에 대해서는 말이 많습니다만 저는 개체란 용어를 쓰겠습니다.) 처음에 레고 블록을 조립하듯이 프로그래밍을 하면서 생산성은 향상되었지만 기능별로 쌓아서 프로그래밍을 해도 문제가 되는 대형 프로그램의 시대가 왔기 때문입니다. TV, 컴퓨터, 라디오 대부분의 전자제품에는 "전원버튼"이 있습니다. 이것을 구현하기 위해서는 TV에 전원버튼이라는 모듈을 만들고 컴퓨터에 전원버튼이라는 모듈을 만들고 라디오에 전원버튼이라는 모듈을 만들어야 합니다. 그런데 이렇게 하나하나 설계해서 만들어야 한다면 바퀴는 자전거에 붙일때 발명되어야 하고 자동차에 붙였을때 또 새로 발명되어야 할것입니다. 우리의 생각하는 방식과 프로그래밍하는 방식이 일치하지 않은 것이지요.
그런데 라디오의 전원버튼, TV의 전원버튼, 컴퓨터의 전원버튼을 추상해봅시다. 구체적인 특성은 없지만 전원이라고 하는 개념은 동일하지요. 이것을 하나로 묶습니다. 실제로 전원버튼이 똑같다면 실제로 그렇게 만들고 TV에도 붙이고 컴퓨터에도 붙이고 라디오에도 붙이면 되죠. 이것도 "전원"이란 개체이죠. 그런데 컴퓨터의 전원과 진공청소기의 전원이 똑같지는 않죠? 그렇지만 똑같이 제품을 켜고 끈다는 것은 동일하죠. 그러면 일단 "전원"이라는 개체에는 똑같이 켜고 끄는 방식이라는 것만 프로그래밍합니다. 그리고는 "전원"을 이용해서 "컴퓨터의 전원"을 만듭니다. 그리고 또 "전원"을 이용해서 "진공청소기의 전원"을 만듭니다. 작업의 양은 3번 반복했으니 더 많아 진것 같죠? 하지만 작업의 양은 더 짧아지게 됩니다."진공청소기의 전원" "컴퓨터의 전원" 사이에 공통점을 "전원"이라고 미리 만들어주고 양쪽에서 그걸 쓰고 있으니 공통된 부분은 1번만 만들면 되는 것이지요. 이것은 "전원"이라는 개체를 만들었기 때문입니다.
=====
우선 모듈이란 말과 객체란 말은 서로 비교의 대상이 될 수 가 없다고 생각됩니다. 왜냐하면 쓰이는 방식이 다르다고 할까요..??
우선 객체는 객체 지향 프로그램밍을 하다보면 지겹게 듣는 말이기도 한데여 우리가 추상화 할 수 있는 어떤 대상(Entity)를 하나의 객체로 볼 수가 있습니다. 즉, 사람도 하나의 객체이고, 책상, 모니터, 키보드도 하나의 객체가 될 수있습니다. 추상화 할 수있다는 것은... 우리는 모니터를 보고 아~ 모니터구나 라고 인식을 합니다.. 모니터의 내부 구성이 어떻게 이루어졌는지... 어떻게 화면이 나오는지 몰라도 아 저건 모니터구나라고 알 수가 있죠. 인간은 그렇게 사물을 추상화 할수있는 능력을 가지고 있다고합니다. 즉 객체지향 프로그램이야 말로.. 우리가 늘 하던것...을 프로그램밍으로 하는것이라고 말하는 사람도 있습니다.
객체지향 프로그램밍에서.. 이런 객체들을 말들고자 할때.. 객체를 만들기위한 일종의 템플릿이 필요하게 됩니다. 즉.. 쉽게 말하면 만약 모니터를 예를 든다면.. 삼성모니터, LG 모니터 등등이 있을겁니다. 물론 같은 모니터라고 볼수가 있겠죠. 객체지향 프로그램밍에서 삼성모니터, LG 모니터를 객체로 본다면 모니터는 클래스라고 할 수 있습니다. 즉, 클래스는 객체를 만들기위한 템플릿, 이라고 말하기도 합니다. 예전에 템플릿자 써보셨져..?? 삼각형, 사각형, 원을 그릴수 있는...
그럼 모듈화는 어플리케이션을 예를 들면 하나의 기능을 갖는 패키지라고 볼수가 있습니다.
만약 게시판을 만든다면, 게시판 글 관리, 회원관리가 각각의 모듈이라고 생각할 수 있습니다.
어떤 기능을 위한 묶음... 좀 이쁜말은 아니지만... 도움이 되셨는지 모르겠습니다.
=================================================
객체지향프로그래밍은 객체라는 작은 단위로서 모든 처리를 기술하는 프로그래밍 방법으로서, 모든 처리는 객체에 대한 요구의 형태로 표현되며, 요구를 받은 객체는 자기 자신 내에 기술되어 있는 처리를 실행한다. 이 방법으로 프로그램을 작성할 경우 프로그램이 단순화되고, 생산성과 신뢰성이 높은 시스템을 구축할 수 있다
==================================================================
객체 지향 (Object-Oriented)
객체지향이란 용어는 Simula 67 프로그래밍 언어에서 객체(object)라는 개념을 사용한데서 유래했다.
객체는 시스템을 구성하는 실체(entity)로서 각 객체는 한 구성원의 특성과 상태변화를 구현하는 기본 단위라 할 수 있다.
객체는 소프트웨어를 구성하고 실제 소프트웨어를 작동시키는 실체들
즉, 논리와 데이타가 분리되어 있는 기존의 구조적 사고에서 과감히 탈피하여 논리와 데이타가 결합된 객체들이 시스템을 이룬다는 것이다.
객체지향이란 소프트웨어를 자료구조(data structure)와 행위(behavior)가 결합된 객체들의 구조화 된 집합으로 보는 시각이다. 소프트웨어를 구현하는 방법이라기 보다는 실세계의 문제를 보는 개념이다.
객체의 속성 (Attribute of object)
다음의 항목들은 객체가 지니는 속성을 보여준다.
Identity(식별) - 각 객체는 다른 객체로부터 분리되고 있고, 분별 가능해야 한다.
Classification(분류) - 같은 자료구조와 행위를 가진 객체들은 동일한 클래스(class)로 분류된다.
상대적으로 각 객체는 소속 클래스의 인스턴스(instance)가 된다.
같은 클래스에서 생성된 객체들은 모두 같은 연산(operation) 기능을 갖고 있으며, 자료구조가 같고 동일한 행위를 하게 된다. 자료구조는 객체들이 갖는 데이타와 속성(attribute)들의 집합입니다.
그러나 데이터와 속성의 값은 물론 다르죠
Polymorphism(다형성) - 같은 연산 기능이 부여되어도 그 기능을 수행하는 클래스에 따라 다른 행위로 나타날 수 있다.
예를 들어 '이동(move)' 이라는 기능이 '교수'라는 클래스에 적용될 때는 자택의 이사가 될 수 있으나, '승용차'라는 클래스에 적용되면 특정 목적지로 일정한 시각에 정해진 속도로 움직이는 행위가 될 수도 있다.
Inheritance(상속) - 계층(hierarchy)관계에 놓여 있는 클래스들 간에 속성이나 연산 기능들을 공유한다.
즉, 주어진 클래스에 서브클래스(subclass)가 있다면 서브클래스의 모든 객체들은 소속 클래스의 모든 속성이나 연산기능을 상속받게 된다. 따라서, 서브클래스를 정의할 때에는 수퍼클래스(super class) 로부터 상속받는 내역들을 중복하여 정의할 필요가 없게 된다.
객체 지향의 기본 원리 (basic principles of object-oriented)
객체 지향 기술은 객체의 identity, classification, polymorphism, inheritance를 유지하기 위하여 다음과 같은 설계의 원칙을 중요시 한다.
data abstraction : 자료 객체(data entity)들의 중요한 특성을 모형화한다. 이 모형이 객체의 속성이 된다.
encapsulation : 객체의 내부적인 사항과 객체들간의 외부적인 사항들을 분리시킨다. 이렇게 캡슐화된 객체의 행위는 외부에서 볼 때는 구체적인 아닌 추상적인 것이 되므로 정보 은닉(information hiding) 개념이 존중된다. 주어진 클래스의 특정 연산 기능은 메소드(method)라고 한다. 캡슐화는 무슨 메소드로 구현되었는가에 구애받지 않고 추상적으로 정의된 연산 기능을 통해 객체가 사용되고 시스템의 상태(state)를 변화시키도록 해준다.
combining data and behavior : 특정한 연산 기능을 수행시킬 때 단순히 메세지만 전송하면 된다.
sharing : 자료 구조및 행위의 공유화(sharing)는 계층 관계에 놓여 있는 클래스들 간의 상속성(inheritance)으로 가능하다.
상속성은 설계 및 코드의 재사용(reuse)을 도와주는 중요한 개념이다.
서브클래스가 수퍼클래스의 변수와 메소드들을 상속받을 때 필요에 따라 정의가 구체화(specification)되며, 상대적으로 상위층의 클래스 일수록 일반화(generalization) 된다고 말한다.
객체지향 개발 단계
일반적으로 널리 사용되고 있는 분석, 설계, 구현 단계로 분리한다.
1. 객체지향 분석(object-oriented anaysis : OOA)
문제를 정의하고 이 정의로부터 모형(model)들을 제작하여 실세계(real-world)의 중요한 특성들을 보여주는 단계이다. 다음과 같은 모형 들이 만들어 질 수 있다.
객체 모형(object model) : 객체들과 그 특성을 식별하여 객체들의 정적 구조(static structure)와 그들간의 관계(interface)를 보여주는 객체 다이어그램(object diagram)을 작성한다.
동적 모형(dynamic model) : 시간 흐름에 따른 시스템의 변화를 보여주는 상태 다이아그램(state diagram)을 작성한다. 실시간(real-time) 시스템에서는 반드시 필요하다.
기능 모형(fuction model) : 시스템 내에서 데이타 값이 변하는 과정을 보여주는 것으로 잘 알려진 자료 흐름도(DFD)가 사용된다.
2. 객체지향 설계(object-oriented design : OOD)
객체지향 설계는 시스템 설계와 객체 설계로 크게 나뉘어진다.
시스템 설계(system design) : 시스템의 구조를 서브시스템으로 분해한다. 이 과정중에서 성능 최적 방안, 문제 해결 전략, 자원 분배 등이 확정된다.
객체 설계(object design) : 구현에 필요한 상세한 내역을 설계 모형으로 제작하고 상세화된다. 구체적인 자료구조와 알고리즘 들이 정의된다.
3. 객체지향 구현(object-oriented programming : OOP)
설계 모형을 특정 프로그램 언어로 번역하는 작업이다. 객체, 클래스, 상속의 개념을 다 포용하는 객체지향 언어(object-oriented programming language : C++, Smalltalk 등)가 가장 좋지만 객체의 개념만 인정하고 클래스, 상속 등은 고려하지 않은 객체기반 언어(object-oriented based programming language : Ada 등)도 좋다.
또한, 일반적인 구조적 프로그래밍 언어(structured programming language : C, Pascal 등)도 객체지향 개발에 활용될 수 있는가 하면 객체 지향 데이타베이스 관리시스템(OODBMS)이 개발의 도구로 이용될 수도 있다.
객체지향의 초기개념은 프로그래밍 언어로부터 시작됐으나, 이젠 실세계를 바라보는 새로운 시각으로 그 중요성이 변화하고 있으며, 개발언어에 너무 종속될 필요는 없다.
객체 지향 프로그래밍 개념
객체 지향의 개념을 상세하고 좀 더 직접 느낄 수 있는 수준으로 다루도록 하겠습니다.
객체 지향 기술에서 가장 근본이 되는 개념은 주어진 문제를 이해하고 관찰하는 시각에 있다. 즉, 주어진 문제 영역을 그 안에 존재하며 관련된 여러 개의 객체들이 서로 정보를 주고 받는다고 보는 시각이다. 이것은 우리가 프로그래밍을 하는 것을 제하더라도, 일상 생활에서 어떤 문제에 대해 생각하고 이해하며 관찰하는 방법과 동일하다.
소프트웨어에 대한 종전의 시각은 "하나의 프로그램은 필요한 데이타 구조와 이 데이터구조 위에 수행되는 함수들의 집합"이다.
PROGRAM = DATA STRUCTURE + FUNCTION
이러한 방식의 큰 문제는 연관이 많은 데이터와 함수들도 별도의 독립된 것처럼 코드상에 정의, 취급하는 것이다. 즉, 데이터 부분은 주로 전역 변수(global variable)들의 정의 부분에 포함되어 있고, 이 데이타 부분과 연관된 함수들은 다른 함수들과 함께 정의되어 있어 이들간의 연관관계를 잘 표현하지 못하고 있다.
반면에 객체지향적인 시각은 "하나의 객체지향 프로그램은 여러개의 객체(object)들로 구성이 되며 각각의 객체들은 위에서 언급한 데이터 구조 부분과 관련된 함수들을 동시에 포함하고 있다"는 것이다.
OBJECT = DATA STRUCTURE + FUNCTION
PROGRAM = { OBJECT }
1. 객체 (object)
객체란 필요한 데이타 구조와 그 위에서 수행되는 함수들을 가진 하나의 소프트웨어 모듈이다.
즉, 각 객체의 데이타구조는 상태(state)가 되는 것이다.
예로서, 객체는 단순한 하나의 변수,
int x;
라고 정의된 "x"와는 다르다.
"x"는 하나의 정수를 정의하는 장소만을 제공할 뿐, 어떤 기능을 수행할 수 있는 능력은 없다.
반면에, 객체는 이러한 "x"와 같은 변수들을 가지고 있으면서, 이들 변수를 위에 작동하는 기능들을 함께 지니고 있다. 다음은 C++를 가지고 스크린상에 점을 정의하는 객체의 표현이다.
clss POINT
{
int xPos;
int yPos;
ColorType clr;
public :
...
void move(int x, int y);
void setcolor(ColorType z);
...
}
위에서 보듯이 객체는 단순한 변수만 가지는 것이 아니라, 그 객체가 할 수 있는 일들을 함께 정의한다. 즉, 이것이 캡슐화(encapsulation)의 개념이다.
2. 캡슐화 (encapsulation)
일반적으로 우리 생활에서 어떤 정보와 어떤 종류의 작업은 개념적으로 서로 연관되어 있음을 많이 접한다. 이러한 연관된 정보와 작업 또는 기능을 하나로 묶는 것은 자연스런 과정이다. 예를 들어 대학교의 인사관리에서는 학생들의 이름, 주소, 학번, 전공 들의 정보를 유지하며 학생들에 관해 가능한 작업인 평점 계산, 주소변경, 과목신청 들의 기능들을 생각할 수 있다. 이러한 정보와 정보 처리에 필요한 작업, 즉 기능들은 모두 학생에 관한 것이므로 학생이라는 테두리로 묶어두는 것이 자연스러운 것이다. 이렇게 연관된 사항들을 하나로 묶는 것을 캡슐화(encapsulation)라고 한다.
프로그램상에서의 캡슐화의 의미는 프로그램 분석자나 설계자가 주어진 문제를 데이타와 함수들의 세부사항들은 개발의 차후단계에서 정의하고, 객체라는 덩어리 단위로 문제에 대해 생각하게 하는 추상화의 수단을 제공하는 데 있다.
3. 정보 은폐 (infomation hiding)
정보 은폐란 캡슐속에 쌓여진 항목에 대한 정보를 외부에 감추는 것을 의미한다. 즉, 처리하려는 데이타 구조와 함수에 사용된 알고리즘 들을 외부에서 직접 접근하지 못하도록 하고 캡슐 내부의 함수들만이 접근하게 된다. 객체지향에 관한 서적이나 논문에서 이 두가지 개념이 중요시 소개되는 것은 바로 객체라는 것이 캡슐화와 정보 은폐의 원리를 실제의 프로그래밍 언어에서 실현한 것이기때문이다.
객체와 객체 사이의 정보 교환은 외부에 공개하고자 하는 일련의 정보를 public interface로 정의해 외부에 객체들이 이 Interface를 통해서 그 객체와 정보를 교환하도록 한다. 즉, 한 객체의 Public Interface를 그 객체가 "무슨 일을 할 수 있다. 혹은 이 정보는 공개할 수 있다."라고 외부에 선언하는 것이다.
이 Public Interface는 언어에 따라 표현 양식이 다른데, C++에서는 "public"이란 특별 구문을 두어 "public"란에 들어간 항목들만 외부에 공개된다. Effel이란 언어에서는 "export"라는 란에 지정된 항목들만 외부에 공개된다. 앞에서 정의한 POINT라는 객체 정의를 보면 move와 setcolor의 함수들이 외부에서 관찰될 수 있는 public interface임을 알 수 있다. 여기서 한가지 유의할 점은 move와 setcolor라는 함수들이 외부에 보여져 불리워질 수 있는 함수들이라는 것이며 각 함수가 가지고 있는 코드나 알고리즘까지 보여지는 것은 아니라는 것이다. 한 함수가 외부에 보여지는 부분을 signature라고 하며 하나의 signature는 함수의 이름, 입력 매개변수(input parameter)와 출력 매개변수(output parameter)로 구성되어 있다.
위에서 살펴볼 캡슐화와 정보 은폐의 이점은 우선 객체 내부의 은폐된 데이타 구조가 변하더라도 주변 객체들에게 영향을 주지 않는다는 것이다. 예로서, 어떤 변수의 구조를 배열(array)구조에서 리스트(list) 구조로 바꾸더라도 프로그램의 다른 부분에 전혀 영향을 미치지 않는다. 또한 어떤 함수에 사용된 알고리즘을 바꾸더라도 signature만 바꾸지 않으면 외부 객체들에게 영향을 주지 않는다. 예를 들어, sorting 함수의 경우 처음 사용된 sequence sorting 알고리즘에서 quick sorting 알고리즘으로 바뀔때 외부에 어떤 영향도 주지 않는다. 이러한 장점을 유지보수 용이성(maintainability) 혹은 확장성(extendability)이라 한다.
4. 메세지 (message)
객체지향 프로그램에서는 마치 데이타 통신에서와 같이 정보를 메시지라는 덩어리는 서로 주고 받으며, 이 메세지 교환이 객체들 사이에 정보를 주고 받는 유일한 수단이다. 따라서, 하나의 객체지향 프로그램은 메세지 교환을 하며 통신하는 여러개의 객체들로 이루어진다고 정의할 수 있다.
하나의 메세지는 메세지를 받을 수신 객체(receive object)가 누구인가를 명시하며, 그 수신 객체가 수행해야 할 함수의 이름을 지정하고 그 함수를 실행시 요구되는 인자들(arguments)을 포함하고 있다. 실제로 메세지를 보내는 구문은 언어에 따라서 다소 차이가 있지만, 대체로 다음과 같은 것이 메세지의 일반적인 형태이다.
<수신 객체> <- <함수이름> <필요한 인자들>
예를 들어, 한 '점'이라는 객체에 C++에서는 다음과 같이 메세지를 보낸다.
myPoint.move(10, 15)
여기서 "myPoint"는 한 점을 나타내는 객체이며 다음 부호 "."는 "move"라는 메세지가 "myPoint"라는 객체에게로 전해진다는 메세지 전달의 표현이다. 괄호 안의 숫자들은 인자들이다.
5. 클래스(class)
우리의 일상생활을 보면, 대부분의 사물에 종류나 유형이 있음을 알 수 있다. 예를 들면, 자동차가 무수히 많지만 승용차, 화물차, 버스 들으로 그 종류를 나눌 수 있고, 또 자동차를 모델별로 분류할 수도 있다. 이 때 각 사물이 어떤 유형에 속하는데 이러한 사고 방식을 객체지향에서는 직접 표현할 수 있게 해준다. 즉, 각 객체에는 어떤 종류나 유형이 있는데 각각의 자동차는 별개의 객체지만 여러개의 유사한 자동차들이 하나의 자동차 유형에 속한다. 이러한 객체의 유형을 객체의 타입(object type) 혹은 객체클래스(object class)라 한다. 그리고 한 클래스에 속하는 각각의 객체를 그 클래스의 인스턴스(instance) 혹은 그냥 객체라 한다.
이러한 클래스를 C++로 정의해 보면 다음과 같다.
class Employee
{
char *name;
positionType position;
int salary;
phoneNumberType phoneNumber;
...
public
promote(...
increaseSalary(...
changePhoneNumber(...
...
}
이 클래스 정의에 따르면, Employee 클래스에 속하는 모든 객체들, 즉 모든 직원들은 이름(name), 직위(position), 월급(salary), 전화번호(phone number)등의 변수들을 가지며 진급(promote), 월급인상(increaseSalary), 전화 번호 변경(changePhoneNumber)등의 함수들을 수행시킬 수가 있다.
따라서, 클래스란 각각의 객체들이 가져야 할 속성을 정의하고 있는 본형(template)이며 프로그램 수행시에는 이들 클래스에 근거해서 각각의 객체, 즉 인스턴스를 생성시켜 동작하게 한다. 예를 들어 직원(employee) 클래스에서 "astre"라는 인스턴스를 만들때 C++에서는 다음과 같이 표현한다.
employee astre();
혹은
employee *astre = new employee();
6. 속성 상속(inheritance)
속성 상속이라는 개념 역시 우리의 일상 생활에서 흔히 사용하는 개념을 프로그램으로 표현하기 위한 편리한 수단이다. 어떤 객체의 종류, 즉 클래스는 좀 더 세분화하여 분류할 수가 있는데 이렇게 세분화된 종류나 유형을 subtype 혹은 subclass라고 한다.
객체지향 프로그래밍에서 "속성 상속"은 새로운 클래스를 정의할 때 모든 것은 처음부터 다 정의하는 것이 아니라 이미 존재하는 유사한 클래스를 바탕으로 하여 필요한 속성만 추가하여 정의하는 경제적인 방법을 의미한다. 이 때 새로이 생기는 클래스를 subclass라 하고 그 바탕이 되는 클래스를 superclass라 한다. 이렇게 하면 클래스들 사이에서 공통으로 가지는 특성, 즉 데이타 구조나 함수들은 중복하여 정의하는 일을 줄일 수 있을 뿐 아니라, 특성을 수정하거나 추가시에 superclass의 정의만 고치면 그 subclass들도 변경된 속성을 자동적으로 상속받게 되므로 매우 편리하다.
7. 복수 속성 상속(Mutiple Inheritance)
일반적으로 하나의 subclass는 하나의 superclass를 가지나 문제에 따라서는 복수의 superclass들을 필요로 하는 경우가 있다. 이런 상속 관계를 복수 속성 상속(Multiple inheritance)이라 하는데 일부의 객체 지향 언어에서만 지원되고 있다. 이것은 실제의 문제를 분석하고 모델링 하는데 더욱 편리함을 준다.
8. 추상 클래스(Abstract Class)
클래스 중에는 인스턴스(instance)를 만들어 낼 목적이 아니라 subclass들의 공통된 특성을 추출하여 묘사하기 위한 클래스가 있는데, 이를 추상 클래스(Abstract class, Virtual class)라 한다. 변수들을 정의하고 함수중 일부는 완전히 구현하지 않고, Signature만을 정의한 것들이 있다. 이들을 추상 함수(Abstract function)라 부르며, 이들은 후에 subclass를 정의할 때에 그 클래스의 목적에 맞게 완전히 구현된다. 이 때 추상 클래스의 한 subclass가 상속받은 모든 추상 함수들을 완전히 구현했을 때, 이를 완전 클래스(Concrete class)라고 부른다. 이 완전 클래스는 인스턴스를 만들어 낼 수 있다.
추상 클래스의 예로서 프린터 소프트웨어를 생각해 보자. 우선 모든 종류의 프린터들이 공통으로 가지는 특성을 정의한 추상 클래스 "Printer"가 있다고 한다면, 여기에는 프린터의 상태를 나타내는 변수, 프린터의 속도 등의 변수가 있으며 함수로는 프린팅을 수행하는 Print 등을 생각할 수 있다. 그러나 프린터마다(Dot matrix printer, Laser printer, Ink jet printer) 프린팅 하는 방법이 다르므로 이 추상 클래스 안에서는 Print라는 함수를 완전히 구현할 수 없다. 다만, 여기에는 Print 추상 함수의 Signature만 가지고 있으며, 실제의 구현은 여러 subclass에서 각 프린터 종류에 알맞게 하면 된다.
"Printer"라는 클래스는 추상 클래스로서 실존의 어떤 프린터 기능을 가지고 있지 않고, dot matrix printer나 laser printer 등의 완전 클래스들 간의 공통된 특성만 지정하고 있으므로, 그 인스턴스를 만드는 것은 무의미하다. 추상 클래스는 점진적 개발 방법(Incremental Development)에 유용하게 사용될 수 있으며, 공통 속성(attribute)의 추출 및 정의에 유용하므로 문제를 모델링하는데 편리함을 더해준다.
9. 다형성(Polymorphism)
객체 지향 프로그램의 중요한 특징으로 하나의 함수 이름이나 심볼이 여러 목적으로 사용될 수 있는 다형성(Polymorphism)을 들 수 있다. 객체 지향에서의 다형성이란, 복수의 클래스가 하나의 메세지에 대해 각 클래스가 가지고 있는 고유한 방법으로 응답할 수 있는 능력을 말한다. 즉, 별개로 정의된 클래스들이 ㅌ은 이름의 함수를 별도로 가지고 있어 하나의 메세지에 대해 각기 다른 방법으로 그 메세지를 수행할 수 있는 것을 의미한다. 예를 들어, 여러 가지 화일(file)들을 프린트 하는 함수를 생각해 보자. 화일에는 간단한 텍스트 화일(text file), 문서 편집기로 만든 포멧 화일(format file), 그래픽을 포함하는 화일(file with graphics) 등 여러 가지가 있다. 이들 각각의 화일들은 프린트 하는 방법이 모두 다르다, 객체 지향에서는 아래처럼 각 종류의 화일을 별도의 클래스로 정의하고, 각각의 화일 종류별로 Print라는 함수를 화일의 형태에 맞게 구현한다.
Text file -> Print();
Formatted file -> Print();
File with graphics -> Print();
이렇게 생성된 화일 객체들은 모두 Print라는 메세지를 이해하며, 각 화일의 종류에 알맞게 프린트 할 수 있다. 이렇듯 다형성은 같은 이름의 함수를 여러 클래스가 각 클래스에 알맞게 달리 정의하고 같은 이름의 메세지에 응답할 수 있게 해준다.
객체지향 프로그래밍의 장점
생산성 향상(Improvement of productivity)
객체지향 기술에서 추구하는 궁극적인 목표는 잘 설계된 클래스들, 즉 하드웨어의 IC처럼 소프트웨어 라이브러리(library)를 재사용하는 것이다. 종전의 개발 방법과는 달리 객체(object)는 IC처럼 독립적이어서 이를 재사용함으로 생산성(productivity)이 증가하게 된다. 어느 한 보고서에 의하면 객체지향 소프트웨어 개발에 기존 클래스의 재사용률이 80%에 이른다고 한다.
자연적인 모델링(Natural modeling)
객체, 클래스, 속성 상속 및 다형성(polymorphism) 등은 우리의 일상생활에서 보통 사람들이 대하고 생각하는 방식을 그대로 프로그램 언어로 표현할 수 있게 해준다.
재사용(Reuse)
객체지향 프로그래밍은 코드의 재사용을 극대화한다. 한 프로그램 내에서 subclass들이 superclass의 속성을 표현한 코드를 재사용하며, 새로운 프로그램 개발시 기존 프로그램이 갖고 있는 클래스 상속 구조에서 많은 클래스들을 소프트웨어 IC로 재사용할 수 있다.
유지보수(maintenance)의 용이성
객체지향 프로그램은 기존의 기능을 수정하거나 새로운 기능을 추가하기가 용이하다. 기존 기능을 수정시 함수를 새롭게 바꾸더라도 캡슐화와 그 함수의 세부정보가 은폐되어 있어 주변에 미치는 영향을 최소화 한다. 새로운 객체의 종류를 추가시에는 속성 상속을 통하여 기존의 기능을 활용하고 존재하지 않은 새로운 속성만 추가하면 되므로, 매우 경제적이다.
이외에도 점진적(incremantal) 프로그램 개발의 용이성, 요구사항(requirement) 변화에 대해 안정된 프로그램 구조 등의 장점들을 들수 있다.
객체지향 프로그래밍의 단점
객체지향 프로그램의 유일한 단점으로 실행시의 속도(runtime efficiency)가 떨어진다고 알려져 왔다. Smalltalk이나 C++ 등의 객체지향 언어로 만들어진 응용 프로그램은 Fortran이나 C 등의 재래식 언어로 만들어진 프로그램에 비해 실행 속도가 늦다는 말을 흔히 듣게 된다. 이것은 유연성(flexibiblity)와 효율성(efficiency)의 trade-off 관계에 기인한다.
객체지향 프로그램은 객체라는 단위를 컴퓨터의 기억장치에 어떤 형태로든 표현해야 하고, 객체간의 정보교환이 모두 메시지 교환을 통해 일어나므로 재래식 프로그램보다 실행시스템에 많은 부하(overhead)가 생기게 된다. 하지만, 이러한 운용시 호율성 문제는 효율성이 뛰어난 새로운 언어들의 탄생으로 이제 거의 문제가 되지 않는다. 특히, 기존의 언어 C나 Pascal 등을 확장한 C++나 Object Pascal 등은 기존 언어의 효율성과 객체지향의 장점들을 모두 제공한다.