C++ 클래스에 대한 메모2. 상속메커니즘

프로그래밍/C++ 2006/05/04 22:19
C++ 클래스에 대한 메모2. 상속메커니즘 http://www.xevious7.com

사실 클래스라는 개념은 객체지향 프로그래밍의 꽃이라고 할 수 있습니다.
그런데 문제는 이 개념이라는 것이 생각보다 어렵다는 것입니다. 일반적으로 말입니다.
마치 C언어를 배울때 처음 접하는 포인터라는 개념을 이해할 때처럼 그것보다 훨씬
어렵게 다가온다는 사실입니다.

이러한 것에 대한 문제는 조엘 스폴스키의 블로그베스트 책의 글에 보면 매우
명쾌하게 설명되어있습니다.

5장 애덤 보스워드(현2006 구글부사장) ICSOC04 강연 한 토막 이라는 글과
그 글을 소개하는 조엘씨의 글을 한번 읽어봅시다.

많은 사람들은 자신이 바보취급 받기가 싫은 나머지 어렵다는 말은 하지 않는
경향이 있다는 사실있다는 것입니다.

여기서 부터 책인용 :
 
" 정말 똑똑한 컴퓨터공학자들은 자신들의 지적능력을 이용해서
     시스템 설계를 단순화시키기 때문에 일반인들은 이를 쉽게
     활용할 수 있습니다."

  결국 역사적으로 중요한 의미를 갖게 되는 시스템은 이렇게 단순화된
시스템이랍니다. ...

중략

매우 복잡한 명세서의문제점은 사용자가 다른 사람에게 멍청하게 비춰질 것을
두려워한 나머지 설계자에게 시스템이 너무 복잡하다는 이야기를 절대 하지
않는다는 것입니다. C++는 해를 거듭하면서 마치 비잔틴 양식의 건축물처럼
복잡다단하고 이해하기 힘든 형태로 변형되왔습니다.
그러나 "이제 좀 그만둬요! 이건 도대체 인간이 이해할 수 있는 수준이
아니라구요!"라고 불평하는 사람은 아무도 없었습니다. 아무도 멍청해 보이고
싶지는 않았기 때문입니다. 그러나 사람들은 겉으로 불평하는 대신, 비주얼
베이직이나 PHP, 펄Perl 처럼 어리석은 중생들도 충분히 이해할만한 기술을
사용함으로써 묵묵히 자신들의 성향을 뚜렷하게 보여주고 있습니다.
... 후략

조엘씨의 말이 모두 옳다는 아니지만 C++이 어려운 것은 사실 인가 봅니다.
그래서 만약 그것을 잘 이해 못한다고 해도 우리들의 잘못은 아닌 것이죠 ~

이러한 이유로 이런것들은 좀더 쉽게 또는 여러가지 방법으로 이해하기 위해서
여러 좋은 책들을 그리고 좋은 글들을 생각들을 많이 보고 읽어야 합니다.
그중의 하나가 Design Pattern 이라는 책입니다.

그런데 사실 이책도 매우 좋은 책이지만 여타의 프로그래밍 책처럼 딱딱하기
그지 없는 책인것 같습니다.

똑같은 내용을 다루면서 쉽게 볼 수 있는 책은

다행히도 이런것을 잘 아는(지루하지 않게 공부하는방법)
저자들이 새롭게 쓴  Head First Design Pattern
이라는 책이 있습니다.

C++를 공부하는 입장에서 본다면 이책의  단점은
Java를 기반으로 해서 설명을 한다는 것입니다.

하지만 어려운 책이 싫고 좀더 올바른 객체 지향 프로그래밍을
하고자 한다면  유용하지 않을까 생각합니다.


비야네 스트롭스트룹씨의 C++ Programming Language 에서는  객체지향 프로그래밍을
쓰면서 이런 예를 들어 설명합니다.

그래픽 시스템에 사용하려고 하는 Shape 라는 타입을 하나 정의하려고 할때 생기는
문제점에 대해서 설명합니다.

Shape에는 사각형 , 원, 삼각형 들이 있을 수 있는데
따라서 대략적으로 클래스를 작성해보면

enum Kind { circle , trigangle, square } ;

class Shape {
        Kind k;   // 도형타입
        Point center;
        Color col;
// ..
public
    void draw()
    void rotate(int) ...

이렇게 정의 될수가 있습니다.  즉 데이타형과  행동할수 있는 메서드로
분리해서 말입니다. 그런데 이렇게 되었을 경우 draw함수나 rotate함수는
모양에 따라서 다른 행동을 취해야 한다는 것입니다.
즉 도형타입이 무엇인지 검사해야 되고 그것에 따라서 다른 코드를 가져야 한다는것입니다.
예를 들면 다음처럼 코드가 구현 될 것입니다.

void Shape::draw()
{
  switch(k) {
                case cricle: ......//코드내용 // break;
                case triangle: .... break;
                case square:...   break;
  }
}
사실 이렇게 만약 클래스가 쓰인다면 ..  비야네씨의 책 그대로 적어본다면
산업쓰레기다움의 코드라고 까지 표현하는 군요. ㅠ.ㅠ

(
별로 바람직한 표현은 아닌 것 같습니다.

개인적인 생각으로는 한 함수가 타입을 검사하고 코드가 다르게 구현된다고 해도
그 부분이 크지 않다면  가상함수를 써서 그 작은 코드수정을 위해서 서브 클래스를
만들어 쓰는것이 오히려 낭비라고 생각합니다.


하지만 위의 경우는 설명을 위한 간단한 예라고 생각하면 될 것 같습니다.
클래스 디자인에 있어서 전체부분을 보고 크게 디자인하여 베이스 클래스로부터
  쭉쭉 뻗어가는 큰 디자인을 하는데 있어서 생각하는 문제라고 할까요.
)

새로운 타입을 추가할때마다 클래스의 수정이 이루어져야 하고 소스코드를
손될수 없는 상황에서는 새로운 도형을 추가할 수도 없습니다.

어찌되었든 이정도는 기능은 사실 클래스를 안쓰고 모듈화 프로그래밍 만으로도
충분히 구현될 수 있습니다.
즉 절차적 프로그래밍 언어로도 충분히 코드의 큰 차이 없이 구현가능하다는 이야기
입니다.

여기서 객체지향프로그래밍을 언어적으로 지원할 수 있는지가 중요한 시점이 오는데
책을 인용해보면

'문제의 핵심은, 도형마다 가지고 있는 일반적인 성질(이를테면 도형은 색깔을 가지고
있으며 그릴 수 있다)과 그 도형만의 성질(원형은 반지름을 가진 도형이고, 둥근 선을
그리는 함수로 디스플레이 한다)이 명확하게 갈라지지 않았다는 데 있다
이 차이를 언어로 나타내고 이용하는 것이 바로 객체 지향 프로그래밍이다.'


라고 말하고 있습니다.
즉 클래스를 구현할때  일반적인 성질, 또 특수한 성질 구분하여 디자인 한다는 것입니다.
이것이 첫번째 클래스의 핵심입니다.

이것을 상속 메커니즘이라고 부르고 있습니다. 이것은 시뮬라 언어로부터 C++로 가져온
특성입니다.


그러면 위의 Shape 클래스를 다시 디자인 해보겠습니다.

class Shape {
        Point center;
        Color col;
        // .....  일반적인 특성을 가진 데이타추상화
public
       Point where() { return center; }
       void move(Point to) { center = to; /* ... */ draw(); }
       virtual void draw() = 0;
       virtual void rotate(int angle) = 0;
       // ..
};

위처럼 도형의 특수성에 따라 변할수 있는 부분들은 가상함수로 정의합니다.
(가상함수는 함수의 함수만을 정의하고 내용은 이 클래스를 상속받는
클래스에서 정의하는 함수를 의미합니다.)

그리고나서 특정한 도형을 정의 하는 것입니다.

class Circle:public Shape {
        int radius;
        //... 원만의 데이타 추상화
public:
      void draw() { /* ..... */ }  //  원에 맞는 그리기 함수 정의..
      void rotate(int) {}             // 빈함수: 원은 회전해도 똑같다...
};

위의 첫부분 코드는 Circle 클래스는 Shape 클래스로부터 파생되었으며
Shape 클래스는 Circle클래스의 기본 클래스 이다. 라는 것을 의미합니다.
이런 관계에서 Circle 클래스를 서브클래스라고 하고 Shape클래스를 수퍼클래스라고
합니다. 파생클래스는 기본클래스가 가진 모든 것을 물려받게 됩니다.
이런 클래스의 관계를 이용하는 것을 상속(inheritance)라고 하는 것입니다.

이런것을 상속 메카니즘이라고 하고 이런것을 언어적으로 지원할때 객체지향적
언어라고 하는 것이라는 것이죠.( 물론 이부분은 객체지향의 여러특징중
하나의 기본이 되는 상속에 관한것입니다.)
top

Trackback Address :: http://xevious7.com/trackback/49

  1. 감마 2007/06/27 14:42 MODIFY/DELETE REPLY

    객체지향에 대한 내용을 프로그래밍 언어 관점에서 정리하고 있습니다.

Write a comment