ComputerProgrammingwithGNUSmalltalk:5.6

From 흡혈양파의 번역工房
Jump to navigation Jump to search

예제

이제 실제 예제를 이용하여 우리가 배운 개념을 모두 설명해보겠습니다. 이 예제에서 우리는 동물들에 대한 클래스를 만들 것입니다. Animal이란 이름의 클래스는 모든 동물에 대한 정보를 가지고 있으며, 특별한 클래스 Dog과 Cat은 각 종류의 특별한 정보를 갖고 Animal 객체로부터 도출하였습니다.

"animal.st" 
"객체지향 개념을 보기 위해 동물 클래스를 만드는 프로그램." 

Object subclass: Animal [ 
  | name | 

  animalNumber := 0. 

  <comment: '동물을 정의하는 클래스'> 

  Animal class >> setAnimalNumber: number [ 
    "동물이 몇 마리 있는지 지정하는 클래스 메서드" 
    <category: 'accessing'> 

    animalNumber := number. 

    ^animalNumber 
  ] 

  Animal class >> getAnimalNumber [ 
    "동물이 몇 마리 있는지 가져오는 클래스 메서드" 
    <category: 'accessing'> 

    ^animalNumber 
  ] 

  setName: newName [ 
    "동물의 이름을 정하는 인스턴스 메서드" 
    <category: 'accessing'> 

    name := newName. 
  ] 

  getName [ 
    "동물의 이름을 가져오는 인스턴스 메서드" 
    <category: 'accessing'> 

    ^name 
  ] 
] 

Animal subclass: Dog [ 
  <comment: '개 클래스'> 

  makeNoise [ 
    "개의 울음소리를 가져오는 인스턴스 메서드" 
    <category: 'accessing'> 

    'Woof!' printNl. 
  ] 
] 

Animal subclass: Cat [ 
  <comment: 'A cat class.'> 

  makeNoise [ 
    "고양이의 울음소리를 가져오는 인스턴스 메서드" 
    <category: 'accessing'> 

    'Miaow!' printNl. 
  ] 
] 

dog := Dog new. 
Animal setAnimalNumber: 1.
dog setName: 'Karabash'. 
dog getName printNl. 
dog makeNoise. 

cat := Cat new. 
Animal setAnimalNumber: 2.
cat setName: 'Minnosh'. 
cat getName printNl. 
cat makeNoise.

'Karabash'
'Woof!'
'Minnosh'
'Miaow!'
2


이제 이 프로그램을 한 줄씩 설명해보겠습니다. 먼저 모든 클래스의 조상격인 특수 객체 Object를 상속하여 클래스부터 만듭니다. 여기에는 new와 같이 미리 정의된 유용한 메서드도 따라옵니다.

Object subclass: Animal [
  ...
]


다음으로 name이라 이름붙인 인스턴스 변수와 animalNumber라는 이름의 클래스 변수를 선언합니다. 동물에 대한 이름과 동물의 개체수를 클래스 변수에 담아둘 것입니다.

  | name |

  animalNumber := 0.


클래스에 주석을 쓰는 것은 문서를 남기기 위한 목적입니다.

<comment: 'A class for defining animals.'>


이제 클래스의 동작을 제공할 메서드를 정의해봅시다. 먼저 동물의 개체수를 지정할 수 있는 클래스 메서드를 만듭니다.

  Animal class >> setAnimalNumber: number [ 
    ...
  ]

그리고 동물의 개체수를 얻기 위한 메서드도 만듭니다.

  Animal class >> getAnimalNumber [ 
    ...
  ]


프로그래밍 하는 동안 set-get 과 같은 종류의 쌍을 자주 볼 것입니다. 나중에 그것들을 획득자 getter 와 지정자 setter , 혹은 접근자 accessor 라고 부릅니다.


다음으로 동물의 이름을 지정하고 얻기 위한 접근자를 만듭시다.

  setName: newName [ 
    ...
  ] 

  getName [ 
    ...
  ]


이제 첫번째 클래스 작성을 완료하였습니다. 이 클래스로부터 Dog과 Cat, 두 개의 클래스들을 도출해낼 것입니다.

Animal subclass: Dog [ 
  ...
] 

Animal subclass: Cat [ 
  ...
]


각 클래스는 Animal 클래스로부터 상속하였기 때문에, 이미 setName:과 getName 메서드를 가지고 있습니다. 일부러 다시 작성할 필요가 없습니다. 대신 각 클래스에 makeNoise 메서드를 추가 했습니다. 이러한 방식을 선택한 이유는 각각의 클래스가 고유의 소리를 내기 때문입니다.


코드의 나머지 부분은 시험을 할 목적으로 있는 것입니다. 두 개의 객체를 만들었고, 적절한 메시지를 전달하는 것으로 메서드를 시험합니다.

dog := Dog new. 
Animal setAnimalNumber: 1.
dog setName: 'Karabash'. 
dog getName printNl. 
dog makeNoise. 

cat := Cat new. 
Animal setAnimalNumber: 2.
cat setName: 'Minnosh'. 
cat getName printNl. 
cat makeNoise.


먼저 Dog 객체를 만들고 동물 개체수를 1로 설정한 다음 개의 이름을 ‘Karabash’로 지정합니다. 그리고 개의 이름을 출력하고 짖게 만듭니다. 다음으로 Cat 객체를 만들어서 Dog과 같은 과정을 적용합니다. 이번에는 이름을 ‘Minnosh’로 정하고, 동물 개체수를 2로 설정합니다. 왜냐하면 동물이 두 마리이기 때문입니다.


프로그래밍 유경험자들에게: 실제로 현재와 같은 상속 트리의 디자인이나 동물 개체수를 직접 설정하는 것은 실제 응용프로그램에서는 물론 나쁜 형태입니다만, 예제를 간단히 유지하기 위해 사용하였습니다.


마지막 명령문은 Animal 클래스 안에 유지하고 있는 동물 개체수를 출력하는 것입니다.

Animal getAnimalNumber printNl.


이 예제에서 접근자 메서드들을 상속하는 것을 보았습니다. 접근자 메서드는 클래스 변수와 인스턴스 변수로 구성된 객체의 내부와 소통할 수 있도록 해주었습니다. 우리는 makeNoise를 통해서 다형성( 메시지를 받은 객체가 자신의 클래스에 따라 다르게 행동하는 것)을 살펴 보았습니다. 그리고 Animal 클래스로부터 상속된 모든 클래스에 setName:과 getName 메서드가 있다는 것을 확인함으로써 상속 개념도 볼 수 있었습니다.


Notes