코딩하는 공무원

Alice의 객체 지향 프로그래밍 3대 요소 본문

컴퓨터교육

Alice의 객체 지향 프로그래밍 3대 요소

코딩펀 2010. 3. 24. 14:33

Alice와 연결시켜 객체 지향 프로그래밍 3대 요소에 대해서 이야기해보자. Alice를 학습하고 난 후, Java나 C++와 같은 객체 지향 프로그래밍 언어를 학습할 계획이 있는 분이라면 캡슐화, 상속, 다형성이라는 객체 지향 프로그래밍 3대 요소를 반드시 숙지하고 있어야 한다. 이 3대 요소를 Alice의 기능과 연결시켜 그 핵심 개념만을 간단히 설명한다.

 

 

캡슐화 (Encapsulation)

 

캡슐화는 크게 2가지 의미를 내포하고 있다. 하나는 “관련된 것들을 캡슐로 한데 모은다”는 의미이고, 다른 하나는 “캡슐 내부에 들어 있는 것들을 캡슐이라는 보호막으로 보호 한다”는 의미이다. 첫 번째 의미는 어떤 객체의 속성과 행동을 하나의 클래스에 모아 둔다는 것으로, 이러한 캡슐화를 보통 클래스화(Classification)라고도 한다. 여기서 캡슐이 곧 클래스다. Alice의 갤러리에서 제공하는 각 클래스들이 바로 그 캐릭터와 관련된 속성과 행동을 하나의 캡슐 안에 모아 놓은 것이다. 캡슐화의 두 번째 의미는 캡슐 안에 들어 있는 것들에 대해서 캡슐 외부로부터의 접근을 막는다는 의미로, “클래스 접근 제어”라고도 한다. Java 언어와 같은 일반 프로그래밍 언어에서는 이러한 역할을 public, protected, private 등의 접근 제어자(access modifier)가 담당한다. 이러한 접근 제어자를 통해서 중요한 속성 및 메서드에 대해서는 외부로부터의 접근을 막고, 필요한 속성과 메서드만 공개하는 것이다. 그러나 Alice에서는 프로그래머가 직접 이러한 접근 제어를 할 수 있는 기능이 없으며, 모든 클래스의 속성과 메서드가 외부로 공개되어 있다. 만약 A 객체의 메서드 안에서 B 객체의 속성 값을 설정하거나 B 객체의 메서드를 호출할 수 있다면, B 객체의 속성과 메서드는 외부에 공개되어 있는 것이며 접근 제어가 전혀 안 되고 있는 것이다. 이와 관련된 예로 다음의 그림 1를 살펴보자. 그림의 월드에는 두 개의 요정 객체가 있다. 하나는 leftFantasy이고 다른 하나는 rightFantasy다. 그리고, world.my first method에서는 rightFantasy 객체의 맞춤형 메서드 change를 호출하고 있다. 다음의 그림 2는 rightFantasy 객체의 맞춤형 메서드 change의 모습이다. 메서드 안의 명령문을 유심히 확인해 보라. leftFantasy 객체의 color 속성을 red로 설정하고 있다. 즉, rightFantasy 객체가 자신이 아닌 남(leftFantasy 객체)의 몸 색깔을 붉게 만들고 있는 것이다.

 

그림1. 독립된 두 요정 객체

 

그림 2. 다른 객체의 속성을 변경하는 예

 

만일, 현실 세계에서 이러한 현상이 발생한다면 얼마나 황당할까? 남이 나의 몸 색깔을 자유 자재로 변경할 수 있다면... 상상하기도 싫은 상황이다. 만약, leftFantasy 객체의 color 속성에 Java 언어의 private 접근 제어자가 설정되어 있다면, 그림 2와 같은 명령문은 컴파일 단계에서 에러를 발생시킨다. 여기서 private의 접근 제어가 설정된 속성이나 메서드는 해당 클래스 내에서만 접근할 수 있고, 외부에서는 전혀 접근할 수 없도록 보호된다. 즉, private으로 설정된 속성이나 메서드는 외부 객체의 메서드에 표시되면 안 된다. 글자로 보이면 안 된다는 것이다. 그러나 Alice는 모든 클래스의 속성과 메서드에 대해 외부의 접근을 허용하고 있으며, 따로 이것을 제어할 수 있는 즉, 외부의 접근을 막을 수 있는 방법이 전혀 없다. 따라서 Alice의 캡슐화는 “관련된 것들을 캡슐로 한데 모은다”는 첫 번째 의미가 강하다고 말할 수 있다.

 

 

상속 (Inheritance)

 

객체 지향 프로그래밍에서 상속은 “코드의 재사용성 증가”, “클래스의 계층적 설계”, “다형성”, 이 3가지를 위해 존재한다. 앞 절에서 이미 배웠듯이, 상속은 코드의 재사용성을 증가시킨다. 클래스를 설계할 때, 관련 있는 모든 속성과 메서드를 하나의 클래스 안에 모아 놓는 것이 아니라, 일반적인 속성과 메서드는 상위 개념의 클래스에 모아 놓고, 그 상위 클래스를 그냥 상속받아 사용하는 것이다. 즉, 상위 개념의 클래스로 갈수록 그 클래스는 하위 클래스들의 공통된 속성과 메서드를 가지고 있게 된다. 이렇게 클래스를 계층적으로 설계하면, 코드의 재사용성이 증가됨과 동시에, 프로그램을 계층적으로 설계할 수 있어, 그 프로그램의 유지와 보수가 훨씬 쉬워진다. Alice에서 상속은 월드에 객체를 배치한 후, 그 객체에 맞춤형 메서드를 만들고, 이 객체를 새 클래스 파일로 저장하는 방식으로 이루어진다. 여기서 새로 저장한 클래스가 하위 클래스가 되는 것이고, 갤러리에 기존에 있던 클래스가 상위 클래스가 되는 것이다. 따라하기 5-2(도서 “Alice 컴퓨터 프로그래밍의 시작”에서)의 경우, FlyingPterodactyl가 하위 클래스이고, 갤러리의 Animals 컬렉션에 있는 Pterodactyl 클래스가 상위 클래스이다.

 

상속은 다형성 구현에 큰 역할을 한다. 상속이 없이는 다형성의 구현이 불가능하기 때문이다.

 

 

다형성 (Polymorphism)

 

다형성이란 동일한 메시지에 대해서 이 메시지를 수신한 객체들이 서로 다르게, 그 객체에 맞는 적합한 행동을 하도록 구현하는 객체 지향 기법을 말한다. 상속의 관점에서 다형성을 다시 정의하면 “상위 클래스의 좀 더 포괄적인 개념을 이용해서 하위 클래스들에 동일한 방식으로 접근하되, 그 하위 클래스의 특화된 메서드를 실행하는 기법”이라고 할 수 있다.

 

Java 언어와 같은 일반 프로그래밍 언어는 상속, 메서드 오버라이딩(Method Overriding), 레퍼런스 형 변환 등의 기법들을 조합해서 다형성을 구현한다. 현재 Alice 2.0 또는 2.2는 이러한 다형성을 직접 구현할 수 있는 기능이 없다. 이는 Alice 개발팀의 공식 입장이기도 하다.

 

만약 Alice가 다형성을 지원하고 있다면, 다음에 설명하고 있는 단계들이 가능해야 한다. 다음은 Alice가 다형성을 지원한다는 가정하에 설명한 것이다.

 

우선, 월드에 Penguin 인스턴스를 그림 3 처럼 2개 추가한다. 왼쪽에 있는 인스턴스의 이름은 leftPenguin이고, 오른쪽에 있는 인스턴스의 이름은 rightPenguin이다.

 

그림 3. 월드에 추가한 두 마리 펭귄

 

두 객체 내에 각각 run이라는 이름의 맞춤형 메서드를 만든다. leftPenguin 객체의 run 메서드는 그림 4와 같다.

 

그림 4. leftPenguin의 run 메서드

 

rightPenguin 객체의 run 메서드는 그림 5와 같다.

 

그림 5. rightPenguin의 run 메서드 



메서드의 이름이 run으로 동일하지만, 현재 그 내부 동작은 다르다. leftPenguin의 run 메서드는 앞쪽으로 1미터 이동하고, rightPenguin의 run 메서드는 뒤쪽으로 1미터 이동한다.

 

이번에는 world 객체에 testPoly 메서드를 그림 6과 같이 만든다. 형식이 Object형이고 이름이 abc인 매개변수도 같이 만들었다. 타일 위에 있는 Obj 표시는 이 변수의 형식이 Object형이라는 것을 말해 준다. Object 형식의 변수는 Alice의 모든 객체를 저장할 수 있다. 즉, testPoly 메서드는 Alice의 모든 종류의 객체를 인수로 전달 받을 수 있다. 이렇게 전달받은 객체는 abc 매개변수에 저장된다. 여기서 testPoly 메서드는 인수로 전달된 객체의 run 메서드를 호출한다.

 

그림 6. world.testPoly 메서드

 

my first method에서 testPoly 메서드를 그림 7과 같이 호출하였다. 첫 번째 명령문 타일은 testPoly 메서드를 호출하면서 인수로 leftPenguin 객체를 넘겨주고 있으며, 두 번째 명령문 타일은 testPoly 메서드를 호출하면서 rightPenguin 객체를 넘겨주고 있다. 어떤 일이 발생할까?

 

그림 7. world.my first method

 

만약 Alice에서 다형성이 가능하다면, 왼쪽에 있는 펭귄은 앞쪽으로 1미터 이동하고, 오른쪽에 있는 펭귄은 뒤쪽으로 1미터 이동해야 할 것이다.

 

여기서 독자 여러분이 주목할 부분이 바로 testPoly 메서드에 있는 그림 8의 타일이다.

 

그림 8. run 메서드 타일

 

abc 변수는 Object형으로 testPoly 메서드로 넘어 온 인수를 저장한다. 이때 abc에 어떤 객체가 저장되느냐에 따라, run 메서드는 다르게 수행되는 것이다. 만약 abc에 leftPenguin 객체가 저장되면 leftPenguin 객체의 run 메서드가 실행되어 leftPenguin이 앞쪽으로 1미터 움직인다. 만약 abc에 rightPenguin 객체가 저장되면 rightPenguin 객체의 run 메서드가 실행되어 rightPenguin이 뒤쪽으로 1미터 움직인다. 즉, 동일한 메시지 run에 대해서 매개변수 abc 객체가 서로 다르게 행동하고 있는 것이다!!

 

그러나 아쉽게도 Alice는 이러한 다형성 기능이 없다. 그림 8과 같은 타일은 처음부터 만들 수 없다. Object 형식의 변수에 저장된 객체는 오로지 모든 객체가 공통으로 가지고 있는 기본 메서드만 호출할 수 있다. run은 현재 leftPenguin 객체와 rightPenguin 객체의 맞춤형 메서드다. 위의 그림은 다형성을 설명하기 위해 그림 편집 프로그램으로 조작한 것이다. (깜쪽같지 않나..?)

 

다시 한 번 더 확인하자! 그림 8에 나오는 타일을 만드는 것은 Alice에서 불가능하다. 만약 Alice 3.0에서 다형성이 지원된다면, 이러한 타일을 만들 수 있을 것이다.

 

그러나 솔직히 이야기하자. 사실 위의 그림과 같은 타일을 만들 수 있다고 해서, 이것을 진정한 다형성이라고는 말할 수는 없다. (Alice를 이용하여 다형성을 설명하다 보니, Alice에서 제공하는 기능만 사용했기 때문에 다소 무리를 했다.) Alice에서 진정한 다형성이 가능하려면, 우선 클래스 이름을 프로그래머가 직접 지을 수 있어야 하고, 그 이름으로 된 데이터 형식을 만들 수 있어야 한다. 그리고 그러한 데이터 형식으로 만든 변수는 그 클래스의 인스턴스와 그 하위 클래스의 인스턴스를 저장할 수 있어야 한다. 현재는 객체를 저장할 수 있는 데이터 형식으로 Object 형만 가능하다. 메서드 오버라이딩도 자유롭게 가능해야 한다. 사실 현재 Alice는 약간의 메서드 오버라이딩을 지원하고 있다. 여기서 메서드 오버라이딩(Method Overriding)이란 상위 클래스의 메서드를 하위 클래스에 맞게 재 정의하는 것을 말한다. 맞춤형 메서드를 가지고 있는 클래스로부터 인스턴스를 만들면, 맞춤형 메서드의 내부 모습을 메서드 편집기에서 확인할 수 있다. 이때, 만약 그 내부를 수정한 다음, 객체를 새로운 클래스로 저장했다면, 그것이 바로 메서드 오버라이딩이다. 즉, 상위 클래스의 맞춤형 메서드를 하위 클래스에 맞게 재 정의한 것이다. 그러나 Alice에서는 기본 메서드의 메서드 오버라이딩을 허용하지 않고 있다.

 

지금까지 객체 지향 프로그래밍의 3대 요소에 대해서 Alice의 기능과 연결하여 간단하게 설명하였다. 이 3대 요소에 대해 관심이 있는 분은 Java 언어 전문 서적이나 객체 지향 프로그래밍 설계에 관한 서적을 참고하기 바란다.

Comments