객체 지향 프로그래밍


1 개요

  • 정의

객체 지향 프로그래밍(Object-Oriented Programming), 줄여서 OOP. 배우는 사람을 OOPs! 소리 나오게 만드는 개념, 모든 야매 프로그래머들의 원수

프로그램을 어떻게 설계해야 하는지에 대한 일종의 개념이자 방법론.

  • 상세 절차

프로그램을 단순히 데이터와 처리 방법으로 나누는 것이 아니라, 프로그램을 수많은 '객체'라는 기본 단위로 나누고 이 객체들의 상호작용으로 서술하는 방식이다.

  • 절차적 프로그래밍과 비교

기존 절차적 프로그래밍에서는 함수를(메소드) 기계, 데이터를 원료로 생각해서 데이터가 함수 사이를 통과하면서 차츰 순서대로 가공돼 나가는 방식으로 이해한다면 객체 지향 프로그래밍에서는 데이터를 중심으로 메서드가 데이터에 접근해서 수정한다는 개념이다. 즉 원료가 움직이냐 기계(함수{메소드})가 움직이냐의 차이.

2 역사

2.1 시작과 발전

  • 절차적 프로그래밍

초기 프로그래밍 방식은 절차적 프로그래밍 방식이었다. 학교대사전고등학생 알고리즘처럼 입력을 받아 명시된 순서대로 처리한 다음, 그 결과를 내는 것뿐이라는 생각이 지배적이었다. 프로그램을 명령어의 모음으로 인식한 것이다. 또한 프로그래밍이란 어떻게 어떤 논리를 어떤 순서대로 써나가는 것인가로 간주되었다. 즉, 프로그램 자체가 가지는 기능에 대해서만 신경을 썼지, 이 프로그램이 대체 어떤 데이터를 취급하는 것인가에는 그다지 관심이 없었던 것이다.

  • 절차적 프로그래밍의 문제점

문제는 이 방식은 간단한 알고리즘이면 모를까 조금만 복잡해져도 순서도로 나타내는 것이 불가능할 정도로 꼬인 "스파게티 코드"가 나오게 된다. 간단히 말해서 스타크래프트를 위의 순서도로 그려야 된다고 생각해봐라! 이렇게 꼬인 코드를 다른 사람이 보고 이해하는 것은 거의 불가능하고[1]심지어는 작성한 본인조차도 유지보수에 어려움을 겪게 된다.

  • '구조적 프로그래밍'을 제안

이 문제를 해결하기위해 에츠허르 다익스트라가 1968년 "GOTO문의 해로움"(Go To Statement Considered Harmful)이라는 논문에서 프로그램을 함수(프로시져) 단위로 나누고 프로시져끼리 호출을 하는 구조적 프로그래밍 방식을 제안하면서 이러한 위기를 벗어나게 된다. 프로그램이라는 큰 문제를 해결하기 위해 그것을 몇개의 작은 문제들로 나누어 해결하기 때문에 하향식(Top-down) 방식이라고도 한다.
ByF5M0sIUAATowb.png

  • 불완전한 구조화의 문제점

하지만 함수는 데이터의 처리 방법을 구조화했을뿐, 데이터 자체는 구조화하지 못했다. 이는 전역 네임스페이스 포화 문제(변수 이름을 다 써서 이름 짓기도 힘든 상황(...))를 낳게 되었다. 게다가 실행 콘텍스트를 저장할 마땅한 방법이 없어지는 문제가 생겼다. 실행 콘텍스트는 특히 GUI에서 중요해지는데 어떤 창의 현재 상태에 따라 함수가 실행해야 하는 동작 방식이 달라지기 때문이다. 또한 엉뚱한 데이터가 엉뚱한 함수에 전달돼서 데이터를 오염시키는 문제가 발생하고 그런 가능성 때문에 프로그래머가 한 함수의 거동에 영향을 받는 변수를 조사해야 할 때 모든 변수를 다 조사해야 하는 어려움에 봉착했다. 변수의 갯수가 수백 개 이하인 코드에서야 이게 사람의 힘으로 가능했지 코드의 덩치가 커지면서 함수가 접근할 수 있는 데이터의 범위에 명시적인 제한을 걸어야 하는 상황이 도래했다. 이를 지역 변수나 구조체(struct) 등으로 어찌 제어하고 있기는 했지만 더 근본적인 해결책이 필요했다.

  • 객체 지향 프로그래밍의 등장

이를 극복하기 위한 대안으로 등장한 것이 바로 객체 지향 프로그래밍이다. 큰 문제를 작게 쪼개는 것이 아니라, 먼저 작은 문제들을 해결할 수 있는 객체들을 만든 뒤, 이 객체들을 조합해서 큰 문제를 해결하는 상향식(Bottom-up) 해결법을 도입한 것이다. 이 객체란 것을 일단 한번 독립성/신뢰성이 높게 만들어 놓기만 하면 그 이후엔 그 객체를 수정 없이 재사용할 수 있으므로 개발 기간과 비용이 대폭 줄어들게 된다.

객체 지향 프로그래밍은 등장 당시에는 기존의 절차적 프로그래밍과 비교해 매우 이질적이고, 당시 컴퓨터의 처리능력이 별로 좋지 않아서 별 주목을 받지 못하였다.

  • GUI의 등장

그러다가 GUI가 등장하면서 객체 지향 프로그래밍이 급부상하게 된다. 화면에 떠 있는 여러 개의 창은 각자의 실행 콘텍스트를 가지는데 콘텍스트의 현재 상태(활성화, 비활성화, 최소화 등)에 따라 같은 명령에도 다른 결과를 내보내야 했으며 사용자 상호작용을 위해 이벤트 처리도 수행해야 했다. 특히 이벤트 처리는 비동기적인 속성 때문에 기존 절차적 프로그래밍에서는 일종의 횡단 관심사가 되어 버려 코드 전체에 이벤트 처리 코드가 흩어져 있게 되는 문제가 있었다. 그래서 OOP를 도입하여 이벤트를 받았을 때 수행되는 기능(Event Handler, Callback)을 구현할 수 있는 단일 인터페이스를 정의하고, 프로그래머들은 이를 필요한 형태로 알아서 구현하며, 특정 이벤트가 일어났을 때 실행되어야 하는 기능들을 등록한 다음, 운영체제나 응용프로그램이 실제로 해당 이벤트가 발생했을 때 해당 이벤트에 등록된 이벤트 핸들러/콜백을 주욱 실행하기만 하면 되는 구조가 본격적으로 확산되면서 OOP또한 빠르게 확산되었다.

  • 객체 지향 프로그래밍과 이벤트 드리븐 방식의 차이점

단, 이벤트 드리븐 방식은 객체 지향 프로그래밍과 별개의 개념이다. 사실 이벤트 드리븐 방식은 객체 지향보다 함수형 프로그래밍 언어에서 훨씬 더 잘 지원한다.

예시: 같은 일을 하는 Java와 Scala코드의 GUI로직을 보면 Scala쪽이 압도적으로 단순하다는 것을 알 수 있다. 다만 기존 절차형 프로그래밍 언어가 함수를 일급 객체로 지원하지 않아 콜백 구현이 어려운 문제가 있었고(절차형인 C언어에서는 함수 포인터를 사용한다) 마침 등장한 객체 지향 언어가 인터페이스라는 개념을 제공했기에 이벤트 드리븐 방식에 좀 더 어울렸을 뿐이다. 객체 지향 프로그래밍 개념이 나올 당시에도 LISP등 함수형 언어가 있긴 했으나 기존 프로그래머가 사용하기에는 너무 고수준의 개념을 다루고 있었고 성능도 너무 낮았기 때문에 당시에는 주목받지 못했다. 당장 for루프로 리스트 처리가 가능한데 리스트 해석이니 map/reduce니 고차 함수니 왱왈왱왈 떠들어봤자 현업 프로그래머의 귀에 들어갈 리가 없었다. 물론 지금은 고차 함수니 클로저니 같은 개념까지 도입해야 할 정도로 프로그램의 복잡도가 증가했기 때문에 관심을 보이고 있다. 현대에 만들어지는 프로그램은 그 정도로 복잡해졌다.

2.2 지원하는 언어

  • Smalltalk 언어

앨런 케이가 1972년 팔로 알토 리서치 센터(PARC)에서 만든 Smalltalk가 최초로 OOP를 지원한 프로그램이다. 시뮬레이션 프로그래밍 언어시뮬라-67에서 영향을 받았다.

스몰토크는 앨런 케이가 "누구나 쉽게 사용할 수 있는 컴퓨터"를 만들려고 했던 목적에 따라 만들어졌다. 문제는 앨런 케이가 글을 읽고 쓸 수만 있으면 4-5세의 아이들도 프로그래밍 할 수 있는 것을 이상적인 목표로 했기 때문에 프로그래밍을 하고자 하는 목표를 수학적 논리구조(알고리즘)로 개념화한 뒤에 그에 따라 프로그래밍 하는 게 아니고[2] 비 수학적인 사고로 문제를 해결도록 언어가 설계되어 있었고, 이 때문에 모든 것을 객체 단위로 분해하고 그 객체들이 메세지를 전달하여 문제를 해결하도록 프로그램을 해야만 한다.

  • Ruby & Python

- Ruby: Smalltalk의 계보를 잇는 순수 객체지향 언어로는 Ruby가 있다. 일본 프로그래머 '마츠모토 유키히로'(별명이 Matz 마츠다.)에 의해 만들어졌는데 객체지향 언어이면서 기존의 C++나 JAVA 등에 비해서 쉬운 난이도를 가지고 있다.
- Python: '귀도 판 로썸(Guido van Rossum)'에 의해 만들어진 PythonRuby와 비슷한 구조를 가지고 있으며, 역시 객체 지향을 지원하고 있다. 실제로 프로그래밍을 해 보면 미세한 명령어나 기법 차이 등이 있을 뿐, 거의 형제처럼 가까운 언어들이다. [3]

  • C언어에 객체 처리 기능을 추가

브레스 콕스와 톰 러브는 스몰토크를 보고 새로운 시각으로 객체지향을 바라보았는데 그것은 소스 코드의 수정없는 재활용이었다. 그들은 이 개념을 실제 언어에 적용하여 1983년도에 스몰토크의 객체 처리 방식을 C언어에 추가했다.[4]

  • C++

1983년에 비얀 스트로스트룹이 C언어를 확장시킨 C++를 발표했다.

  • Objective-C

1983년에 브래드 콕스와 톰 러브가 C언어에서 파생된 Objective-C를 만들어 발표했고 실제 유용하다는 것을 실증하였다. 그리고, Objective-C는 1989년 당시 가장 혁신적인 운영체제였던 NeXTStep을 개발할때 사용되었다.[5]

  • 기타 여러 언어들

이 두 언어의 성공으로 이후 Java, C\#, Objective-Pascal등 많은 객체 지향 언어들이 순수한 객체 지향보다는 기존의 프로그램 언어에 객체 지향 요소를 확장하거나 추가한 형태로 만들어 지게 되었다.

3 설명

3.1 캡슐화(Encapsulation)[6]

  • 캡슐화의 목적은 코드를 재수정 없이 재활용 하는 것 *

객체 지향 방식의 기본중의 기본 개념이다. 이 캡슐화를 안지키면 나머지 상속과 다형성은 성립이 안된다. 캡슐화의 목적은 "코드의 수정 없는 재활용"을 생각해보면 당연한 개념이다. 프로그램 코드를 재활용 하려고 하는데 기능(함수/프로시저 : 메소드)이 분산되어 있고 특성(변수 : 데이터)이 분산 되어 있는 프로그램 코드는 재활용을 하기 매우 힘들다. 이 때문에 관련 기능과 특성을 한곳으로 모으고 분류할 필요성이 있다.

  • 클래스 & 인스턴스

객체 지향에서는 이렇게 계층적으로 분류한 기능과 특성의 모음을 클래스(Class)라는 캡슐(capsule)에 분류된 집단 별로 각각 집어 넣는다. 이러한 클래스를 실체화(Instance) 하면 객체(Object)를 만들수 있다.

비유 1: 이것을 쉽게 비유하자면 "한국인"이라는 집단(클래스)에 "홍길동"이라는 한국인(인스턴스)을 소속 시킨다(만든다) 라고 할 수 있다.

비유 2: X회사의 고급형 데스크탑(Advanced-Power gaming PC) 브랜드(클래스) -> PC 생산(객체 생성) -> Advance-power gaming PC라는 상품 명으로 생산된 PC 한 대(인스턴스)는 특정한 생산일자와 고유 일련번호(2015-12-25RX, 즉 2015년 12년 25일 날 생산된 PC 한 대)를 가지고 있다. 여기에서 클래스는 일반적인 모델명인 'Advanced-Power gaming PC'(구성품과 스펙은 클래스 내부에 속한 메소드와 변수 등으로 볼 수 있다)를 가리키는 것이고, 인스턴스는 '2015-12-25RX'라는 고유 일련번호를 가진 특정한 'Advanced-Power gaming PC'라는 상품명을 가진 한 대의 PC(인스턴스)만을 가리키는 것이다.
만일 우리가 '2015-12-25RX'라는 PC를 가지고 게임을 하거나 실행하는 것(2015-12-25RX.게임 실행; 2015-12-25RX.인터넷 탐색; 2015-12-25RX.전원 오프 등)은 어디까지나 우리 앞에 놓여진 '2015-12-25RX'라는 실제의 PC를 컨트롤하면서 게임을 하거나 인터넷을 탐색 하는 등의 활동을 하는 것이지. 허상의 'Advance-power gaming PC' 브랜드를 컨트롤 하는 것은 아닌 것이다.

또한, 여기에서 더 나아가자면, 비록 'Advanced-Power gaming PC)'라는 똑같은 모델명(똑같은 클래스)을 가지고 있지만, 생산일자와 장소 등이 달라서 일련번호(2016-2-1AR)가 다른 PC 한 대(즉, 2015-12-25RX와는 완전 다른 '2016-2-1AR'라는 독립된 인스턴스 b)는 완전 PC 한 대이면서 '2015-12-25RX'라는 PC(이미 만들어졌던 과거의 인스턴스 a)와는 완전 별개의 존재다. 그래서 이론적으로는 2015-12-25RX을 포맷을 하든, 게임을 설치하든, 업그레이드를 하든, 오버클럭킹을 하든 간에 이것은 어디까지나 2015-12-25RX(인스턴스 a)에 해당되는 것이지, 완전 별 개인 2016-2-1AR의 PC(인스턴스 b)와는 아무 관련이 없는 것이다.

  • 컴퓨터 내부 처리 절차

객체 생성(생성자): 실제 컴퓨터에서 물리적으로 일어 나는 현상은 "홍길동" 이라는 객체의 생성을 위해 "한국인 Class"에 정의된 데이터가 들어갈 메모리에 할당 하고 기본적인 한국인 클래스의 특성을 초기화 하기 위해 생성자를 호출 하여 "홍길동" 객체를 초기화 한다.

객체 소멸(소멸자): 객체를 메모리에 제거할 땐 할당된 자원(메모리,파일 등)을 정리하기 위해 소멸자(Destructor)를 호출한다. 소멸자의 경우에는 Java.NET Framework같이 가비지 콜렉션이 있는 객체 지향 플랫폼일 경우에는 내부적으로 사용하므로 특별한 경우 외에는 소멸자를 프로그램 코드에 넣지 않는다.

  • 정리

이와 같이 캡슐화는 '클래스, 타입, 인스턴스, 생성자, 소멸자' 같은 객체 지향 프로그램 방식의 기초를 형성한다. 다음에 설명할 상속성과 다양성은 객체의 메카니즘(작동 원리)이기 때문에 캡슐화를 정확히 표현하지 못하면 상속성과 다형성 또한 표현을 잘못하게 되어 있다.

3.2 상속(Inheritance)

사실 클래스 이전의 프로그래밍 기법에선 코드 재활용이 불가능하지는 않았다. 예전에도 라이브러리 등을 통해서 남이 짜놓은 코드를 그대로 가져올 수 있었다.[7]

  • '라이브러리'의 문제점

라이브러리는 코드의 재활용에 지대한 영향을 미쳤지만 치명적인 단점이 있었다. 라이브러리의 기능을 약간 바꾸어야 할 경우 라이브러리의 소스를 변경해야 했고 이 때문에 전혀 다른 라이브러리가 되어 버린다는 것이다. 이것은 라이브러리 버전에 따라 그 라이브러리를 사용하는 프로그램이 동작을 안할수도 있다는 것이고 불필요한 코드의 수정작업을 해야 한다는 것이다.

  • '상속'의 도입

객체 지향 프로그램에서는 이 문제를 해결하기 위해 "상속"을 도입 했다."포용성"으로 이전의 라이브러리보다 더 논리적이고 체계적으로 기능과 데이터를 계층적으로 분류해서 사용의 편의성을 도모하면서, 상속을 사용해 부모 클래스의 특성과 기능을 그대로 이어받고 기능의 일부분을 변경해야 할 경우 상속 받은 자식 클래스에서 그 기능만을 다시 정의하여 수정하게 하였다. 이러한 작업을 "덮어쓰기(재정의 : Override)"라고 한다. 보안이 시망이다

3.3 다형성(Polymorphism)

하나의 변수명, 함수명 등이 상황에 따라 다른 의미로 해석될 수 있는 것을 말한다. 위에서 설명한 오버라이딩 이외에, 변수에 따라 함수의 기능이 달라지는 오버로딩도 여기에 해당한다.

  • 연산자 오버로딩

C++, C# 등에서는 기본 연산자를 오버로딩해서 기본 연산자가 해당 클래스에 맞는 역할을 수행하게 하는 것도 가능하다.

JAVA 등에서는 연산자의 오버로딩이 불가능하다.

펄 6나 스몰토크, F# 등, 연산자의 신규 정의가 가능한 언어도 있다.
한글 위키백과의 연산자 오버로딩에 대한 프로그래밍 언어 분류

4 원칙

객체 지향 프로그래밍/원칙 항목 참조.

5 장단점

하여튼, 이러한 특징은 여차저차한 결과로 다음과 같은 장단점을 지니게 된다.

  • 데이터 클래스 개념은 상속이라는 굉장히 뛰어나지만 마찬가지로 굉장히 개 같은 특성을 지니게 해준다. 이 OOP 특성 덕분에 면밀한 자료 분석[8], 개발시간 단축[9], 좀더 정확한 코딩[10]을 보증하지만 코드의 난이도가 급 상승한다. 한 마디로 어려워진다. 특히, 다중 상속이 되면 엄청 복잡해진다. 그래서 현재에는 다중 상속을 지원하지 않는 OOP 언어가 대부분이며, 다중 상속이 되는 C++ 같은 것도 다중 상속은 최대한 자제하라고 권장하고 있다. 다중 상속의 가장 큰 문제는 순환 상속(죽음의 다이아몬드, the Deadly Diamond of Death라고도 불린다. 상속 항목 참조)의 문제 때문이다. 2개의 부모를 가진 자식 클래스의 조상이 겹치는 경우가 발생할 수 있는데[11]이것을 C++같은 객체 지향 언어는 처리할 수 없다.자식이 부모의 조상이 되어 버릴 수가 있기 때문이다. 이 때문에 상속을 포기하고 필요한 부모의 기능을 다시 모두 구현해줘야 한다. 이렇게 되면 객체 지향 프로그램 방식으로 프로그램했다고 말하기가 민망해진다.
  • 클래스는 오로지 관련 데이터만을 정의하기 때문에, 한 클래스의 인스턴트가 수행될 때 다른 프로그램의 데이터를 절대로 건드릴 수 없게 된다. 덕분에 높은 시스템 보안을 제공하고, 자료 훼손을 방지하는 효과가 있다.[12], Visual Studio 6.0의 C++는 데이터베이스의 자료 처리는 변수를 모두 public으로 처리 했었다.이 이유는 데이터베이스의 필드가 50개이면 get과 set 메소드를 모두 구현해주면 100개의 메소드를 구현해줘야 한다. 변수 50개와 메소드 100개다 150개를 키보드로 쳐야 한다.생각만 해도 일할 기분이 안난다. 이건 Java도 마찬가지다. 변수의 get과 set메소드 구현은 어째던 굉장히 귀찮은 작업이다. 데이터의 은닉도 중요하지만 프로그래머의 손가락 건강도 생각해 봐야 한다. C#은 2.0부터 프로퍼티 하나만 선언해 주면 되기 때문에 상관 없다.[13]
  • 클래스의 정의는 최초로 생성한 프로그램뿐 아니라 다른 OOP에서도 똑같이 사용될 수 있다. 그리고, 이런 이유로 네트워크에 쉽게 분산 사용이 가능하지만 프로그래머에게는 아주 힘든 노력을 강요한다. 네트웍 통신이라는 것은 호환성을 위해 7bit ASCII코드로 전송한다. 1960년대 만들어진 통신기기를 사용하는 곳도 아직 있기 때문이다. 이 때문에 Quarter-Print, Base64나 UTF-8같은 것이 만들어진 것이다. 결국 객체도 7bit ASCII코드로 전송을 해야 한다. 메모리상의 객체 정보를 ASCII 코드 화 하는 것을 직렬화(Serialization)라고 하고 ASCII코드를 다시 객체화 하는 것을 역직렬화(Deserialization)라고 한다. 하지만 마법처럼 그냥 되는 게 아니고 "직렬화 인터페이스"를 프로그래머가 고생해서 구현해 줘서 "직렬화 인터페이스"가 있는 객체만 가능 하다. 현실 세계에서는 마법은 없다. 마법처럼 보이는 것이 있을 뿐이다. [14]
  • 데이터 클래스 개념은 언어에 정의되지 않은 새로운 데이터 형식을 프로그래머가 임의로 정할수 있도록 해준다.

6 기타

참고로, 최근 주목을 받고있는 함수형 패러다임과는 다소 상반된 위치에 있다. OOP 의 경우, 프로그램 유지보수시 데이터 추가는 새로운 클래스를 더하는 것으로 비교적 간단하게 가능하지만, operation set 을 변경할 때는 관련된 다수 클래스를 수정해야 하므로 난잡해지는 경향이 있다. 반대로, 함수형 패러다임에서는 operation set 의 추가는 간단하지만, 데이터 추가는 관련된 다수의 함수를 바꿔야 하므로 난해한 점이 있다. 주의할 점은 OOP 와 함수형 패러다임이 상반된 위치에 있긴 하지만, 대비되는 개념은 아니며, 요즘에는 함수형 언어에도 OOP 개념을 추가한다던가(F#), 반대로 객체지향 언어에 함수형 패러다임을 추가하는(C#, C++, Python 등...)등 멀티패러다임 추세로 가고있다.

클래스가 있어야만 객체 지향 프로그래밍 언어라고 생각할 수도 있지만, 사실 클래스 없는 OOP 언어도 꽤 있다. 프로토타입을 이용하는 JavaScript, 액션스크립트 2.0, 타입 클래스라는 개념을 쓰는 Haskell, 그냥 함수만 써서 다 해먹는(...) LISP등의 각종 함수형 언어 등등...

6.1 교육의 어려움

프로그래밍을 배울 때 만나게 되는 난관이기도 하다. C를 배운 뒤 C++을 배우는 상황에서 특히 심하긴 한데, 곧바로 Java파이썬으로 배우기 시작하는 경우에도 마찬가지이다. 왜냐하면 이전까지 배웠던 것은 프로그래밍 언어의 문법이었다면(절차적 프로그래밍으로서의 문법), OOP는 가장 문제가 덜 생기는 방향으로 코딩하게끔 하는 가이드라인이기 때문이다.(권장사항) 이제 막 알파벳과 기초 영문법을 뗀 학생에게 수사법 내지는 논리적 작문을 가르치는 것과 동일한 것이다.

이 문제라는 것도 수천, 수만 줄짜리 코드를 수년간 유지보수할 때나 몸에 와닿을 텐데, 기껏해야 과제 제출하고 다시 손대지 않을 길어야 수백 줄짜리 코드나 짜봤을 학생들에게는 전혀 체감할 수 없다. 게다가 대부분의 언어들은 기존의 언어에 객체지향을 얹어놓은 형태기 때문에 굳이 OOP에 맞춰서 짜지 않아도 원하는 결과는 일단 나온다. 이러한 이유들로 인해 학생들에게 C++ 과제를 내주면 C++ 문법을 사용한 C 프로그램인 경우가 태반이다.[15] [16]

6.2 C언어로는 OOP 개념을 구현할 수 없다?

위키의 많은 문서에 C언어에는 OOP 개념 따위는 없어 객체 지향의 구현이 불가능하다라는 표현이 많이 보이는데, 이것은 잘못된 서술이다. C언어가 OOP를 문법적으로 지원하지 않는 것은 맞으나 이것은 OOP 구현가능한가와는 다른 문제이다. 리눅스 커널을 만든 Linus Torvalds의 말을 들어보자. "you can write object-oriented code (useful for filesystems etc) in C, _without_ the crap that is C++." 링크 C++가 구리다는 말은 넘어가자

C를 C++로 확장시키고 최초의 C++ 컴파일러를 만든 Bjarne Stroustrup의 경우 처음 컴파일러를 구현할 때 C++를 C 언어로 변환시키는 인터프리터를 통해 만들었다.(물론 현존하는 대부분의 컴파일러는 C++을 C로 바꾸는 작업을 하지 않고 바로 컴파일을 수행한다.) 즉, C로 객체지향 코딩이 가능하다는 말.[17]

Gobject의 경우 C로만 짜여진, 객체지향을 위한, 아니 객체 지향을 위한 크로스 렝귀지 오픈소스 라이브러리이다. 이 라이브러리를 이용해서 구현하면 C 소스인데도 불구하고 Python 등에서 불러 쓸 수 있다.
  1. 특정 코드 부분은 어디에 사용되는 코드고 해당 코드 부분은 어디까지 이어지고, 코드가 어디로 연결되어 있느냐 등을 파악하는 것, 양이 많은 것은 기본이고, 중복 코드도 많이 생길 때 매우 골치 아프다. OOP를 사용하면 코드의 중복을 어느 정도 줄일 수 있고 입력 코드, 계산 코드와 결과 출력 코드 등 코드의 역할 분담을 좀 더 확실하게 할 수 있어서 가독성이 높아질 수 있다.
  2. "1+2" 라는 수식도 수식으로 보지 않는다. "1"이라는 객체에 "+2"라는 메세지를 보내는것으로 본다. 쉽게 말하면 "사과1개"에 "사과2개"를 더하는 유치원생의 사고 방식를 생각해 보면 된다. 그래서, (1+2)X2 같은 연산자의 우선순위의 개념은 당연히 없다. 유치원생은 사칙연산을 이해 못하니까! 근데 이건 앞에서부터 순서대로 하는거 맞잖아?
  3. 생활코딩에서는 이 두 언어를 거의 똑같은 언어라고 설명하면서 루비와 파이썬의 코딩을 동시에 가르치는 강좌를 개설해 놓았다.
  4. C언어의 표준을 지키면서 스몰토크 방식의 객체 처리 기능을 추가했다. 이렇게 표준 언어에 기능을 추가하는 것을 슈퍼셋(Suppeset)이리고 한다. 반대로 표준언어의 기능을 축소한 것을 서브셋(Subset)이라고 한다. 컴파일러 개발 방법을 교육할 목적으로 만든 Small-C가 대표적인 서브셋이다.
  5. NeXTSTEP은 1996년도에 Apple에 인수되어 2001년도에 출시된 Mac OS X의 기반이 되었다.
  6. '포용성'이라고 불리는 경우가 있다.
  7. 라이브러리는 실행될 때만 메모리에 로드하면 되기 때문에 메모리를 아끼는 효과도 있었다.
  8. 단, 초기 개발 요구사항 분석단계에서 팀웍이 안 맞거나 정확하게 하지 못하면 망했어요
  9. 잘 만들어진 클래스는 재사용성을 보장한다. Ctrl C+V신공보다 클래스 재사용이 낫다.
  10. 구현 목적을 위해 클래스를 나눌 수 있으니 구현 단위와 목표가 뚜렷해진다.
  11. 조부나, 증조부나, 고조부 중 누군인가가 겹친다고 생각해봐라
  12. 하지만 public을 남발해 버리면... 더 이상의 자세한 설명은 생략한다. 당연하지만, 이는 프로그램 내에서의 각 인스턴스간 내부적인 접근의 범위를 제한하는 것이다. 외부 프로그램의 메모리 접근 문제와는 다른 범주. 외부에서의 메모리 접근까지 차단한다면 메모리 변조는 어떻게 된단 말인가. 애초에 운영체제에서 메모리 관리도 못하게 될 것이다.
  13. 구체적인 해당 사례를 알 수 없으니 원문을 남겨두지만, 비주얼6는 물론이고 C++ 컴파일러라면 어느 것이든 상속과 타입 선언, 오버로딩 등을 사용하면 public 변수를 사용하는 것과 비슷한 코스트로 메소드를 사용한 입출력을 구현할 수 있다. 메소드가 없으면 클라이언트의 변화무쌍한 갈아엎기에 대한 대응력이 떨어져서 오히려 더 피곤해질 위험이 높은 코드이다. 솔직히 public 으로 도배한 코드는 유지보수 하다가 버그 만들기 십상이라 재활용도 잘 안 하는 망한 코드이다.
  14. 이러한 아이디어를 발전시킨 것이 CORBA와 MS의 COM/DCOM/COM+이다. 최근에는 SOAP나 JSON, XML-RPC등 텍스트 기반의 직렬화 기술도 많이 사용된다. Java에는 Java Runtime 끼리 통신하기 위한 RMI(Remote Method Invocation)도 지원한다.
  15. 이는 JAVA 같은 언어에서 마찬가지로 나타나는 현상이다. JAVA 문법이지만 C 프로그램 처럼 짜는 것을 '씨자바'라고 한다.
  16. 각 프레임들의 입출력 인터페이스를 설계하고 이벤트 드리븐 방식을 정의한 다음 학생들에게 그에 맞춰 오브젝트를 가공하라고 과제 내주는 게 oop 과제인데, 현실은 덜렁 몇 줄의 요구사항으로 전체 프로그램 짜 와라가 전부인 게 보통이다. 그러니 학생들이 기껏 몇 백 줄 짜리 코드 짜는데 functional 로 짜는 것보다 더 효율 좋고 알기 쉽고 간단하게 oop 로 짜라는 건 교수 및 조교들의 망상이다. 자신들도 못 하거나 매우 귀찮아 하는 일을 왜 기껏해야 1-2년 동안 일주일에 3-4시간 교육받은 남에게 시킬까 싶지만 이것이 바로 탁상공론. 그리고 이런 식으로 문제 해결 능력을 키우도록 교육받다 보면 소위 노가다꾼 밖에 양산이 안 된다는 게 현실.
  17. Bjarne Stroustrup가 직접 저술한 The C++ Programming Language 책에 해당 내용을 언급한다.