본디..


C++의 설계자인 바얀(Bjarne Stroustrup)교수님은 Class를 사용자 정의형을 만들기위한 구조라고 하고, 객체지향 프로그래밍이란 사용자 정의형과 상속을 사용한 프로그래밍이다. 라고 했다. C++은 클래스의 개념이 처음 나오고 난 후로부터 10년 뒤 Simula라는 시뮬레이션용 언어를 참고로 사용자가 형을 정의할 수 있도록 만들었다. 


클래스는 type이다. 이거이 C++을 이루는 아주 중요한 원리이다. C++에서 class가 사용자 정의 타입을 의미한다면 왜 그것을 type이라고 부르지ㅏ 않는가? 내가 class를 선택한 것은 계속 나오는 새로운 용어를 발명하는 것이 귀찮았기 때문이고, Simula의 class라면 아무도 당황하지 않을 것이라 판단했기 때문이다.

<C++로 배우는 프로그래밍의 원리와 설게>


int나 float처럼 동일하게 다룰 수 있는 새로운 형을 사용자가 정의하고 사용할 수 있게 하자 라는 것이 C++이 클래스를 도입한 목적이다. 

이렇게 되면서 Type을 자유롭게 만들 수 있게 되었고, MS에서 만든 Visual C++의 경우 너무 많고 다양한 형으로 이제는 사용하기 오히려 어렵기까지 되었다.


C++에서는 클래스를 형(type)으로 보고 객체가 어떤 메소드를 가지고 있고, 가지고 있지 않은가를 구분하는데 중요하게 생각했고 존재하지 않는 메소드를 호출하면 에러가 발생한다. 


하지만 객체지향 용어의 발명자인 Alan Kay는 객체지향이란 상태를 가진 객체가 메시지를 주고 받아서 커뮤니케이션하는 프로그램이라고 말하며, 형이나 상속에 대해서는 부정적인 입장을 취하고 있다. 그가 설계한 Smalltalk이란 것에서는 메소드 호출이란 건 단지 이런 이름의 메소드를 호출해달라는 메시지를 객체에 전달하는 것일 뿐 그 메시지를 받은 객체가 어떤 동작을 할지는 수신 객체가 자유롭게 결정할 수 있다. Alan kay는 이런 자유가 객체지향의 중요한 요소라고 생각한다.



실제로 언어의 성격이나 철학마다 설계자의 생각에 따라서 의미가 조금은 다르다. 실제로 클래스의 의미도 일반적으로 생각하면 위험할 수 있다.


그럼 형이라는 관점에서의 클래스는 어떻게 정의될까?

정적 형결정 언어인 C++에서는 클래스를 사용자가 정의할 수 있는 형이라고 한다. 

동적 혈결정 언어인 Ruby나 Python, Perl, JavaScript의 클래스는 아마 C++의 class와는 다른 의미를 가질 것이다.



보통 C++은 클래스가 없어도 프로그램을 만들 수 있다. Python이나 Ruby도 이와 마찬가지이다. 

하지만 Java는 다르다. Java는 클래스라는 부품을 정의하고, 그것을 조립해나가는 것이 프로그래밍이라고 정의한다. 따라서 Java에서는 클래스는 필수적 요소이다.



클래스는 사실 어떠한 비슷한 것들을 하나로 묶어서 만들자라는 것에 목적을 가진다. 그렇다면 클래스 이전에는 이를 위해 어떠한 개념들이 있었을까?


첫번째는 module이다. 비슷한 기능을 하는 함수를 하나로 모아두는 기능이다. 

1978년경 Modula-2가 개발되었는데 관련성이 높은 함수나 변수의 묶음을 명시하기 위해 Module이라는 개념을 도입했다고 한다.  Ruby나 Python에서는 module이라고 하며, Perl이나 Java에서는 Package라고 한다.


이런 비슷한 것들은 묶으면 현실 세계의 어떤 것을 구현해 낼 수 이씨 않을까? 라는 생각이 등장하게 되었다.


Perl의 package는 함수나 변수를 하나로 묶어서 이름을 붙일 수 있는 기능이다. 하지만 좀 더 완벽한 객체지향을 도입하기 위해서 hash를 사용한다.

자 이유를 생각해보자. pakage를 만들어 하나의 사물을 구현했다. 하지만 그 사물은 여러개일 수 있다. 그럼 이 pakage를 복사해서 pakageA, pakageB 이런식으로 이름을 붙여야 한다. 이게 과연 옳은 것일가? 아니다. 이를 해결하기 위해 별도의 데이터 저장소를 만들어 하나의 이름으로 관리하되 각 객체들이 사용하는 공간을 여러개 두는 개념이 생겼다. 이를 위해 hash를 사용한다. 그리고 추가해야 할 상황이 오면 이와같은 작업을 수행해줄 생성자 함수(constructor)도 필요하다. 이런 초기화 처리도 패키지에 넣는다.

그리고 편리한 사용을 위해 package명과 hash를 연결하는 기능인 bless라는 개념을 발명했고 이를 통해 bless된 hash를 만들어서 보다 편리하게 접근할 수 있도록 하였다.


두번째는 함수도 변수도 동일하게 hash에 넣는 방법이다. JavaScript는 First Class라는 것을 사용하여 구현한다.

일반적으로 대부분의 언어에서 변수에 문자열을 대입하여 사용할 수 있지만, 다 그러한 것은 아니다. FORTRAN66 에서는 문자열을 변수에 대입할 수 없고 C언어 에서는 배열을 인수로 함수 호출을 할 수 없다. 이러한 관점에서 보았을 때 Fisrt Class란 제한이 없는 변수에 대입하고, 함수의 인수로 전들하고, 함수의 반환값으로 전달할 수 있는 것을 말한다. JavaScript에서는 함수도 퍼스트 클래스의 값이라 함수를 변수에 대입하거나 반환값으로 전달하는게 가능하다. 그래서 함수도 hash에 넣을 수 있다.


이렇게 되면 어떤 기능을 하는 객체를 해쉬에 넣고 여러개를 만들 수 있게 되는 것이다. 또한 공유도는 사물은 하나로 묶어서 개별 카운터가 그것을 참조하는 형태로 구현되어 메모리나 시간 절약에 도움을 준다. 


세번째는 Closure이다. 함수 실행시에 이름공간의 변수를 하나로 묶기 위해서 사용하는데, 주로 함수형 언어에서 사용한다.

클로저는 JavaScript에서도 제공한다. 함수를 함수 안에 정의하고, 내포할 수 있는 정적 스코프가 있어서 함수를 반환값으로 사용하거나 변수에 대입하여 사용할 수 있다는 개념이다. 






출처. 코딩을 지탱하는 기술




+ Recent posts