루비로 시작하는 프로그래밍

일반인을 위해 프로그래밍을 가르쳐주는 튜토리얼.

9장. 클래스

Classes

클래스

지금까지 우리는 여러 가지 다양한 객체(또는 클래스)를 살펴 봤습니다. 문자열, 정수, 부동 소수점, 배열, 그리고 나중에 얘기할 몇가지 특별한 개체(true, fales 그리고 nil)들 말이죠..루비에서는 문자열, 정수, 부동 소수점, 배열 등... 요런 일반적인 이런 클래스들은 항상 대문자로 적습니다. 우리가 특정 클래스의 새로운 객체를 만들려면, 지금처럼 사용하면 됩니다.:

a = Array.new  + [12345]  #  Array  addition.
b = String.new + 'hello'  #  String addition.
c = Time.new

puts 'a = '+a.to_s
puts 'b = '+b.to_s
puts 'c = '+c.to_s

#실행결과

a = 12345
b = hello
c = Tue Apr 14 16:29:20 GMT 2009

[...] 와 '...'를 사용하면 각각 배열과 문자열을 만들 수 있습니다. 그래서 배열과 문자열을 만들 때는 보통 new를 사용하지 않죠. 위의 예에서는 그닥 명확하지는 않지만, String.new라고 써주면 비어있는 문자열을 만들어 줍니다. 그리고 Array.new라고 쓰면 배열을 만들어주고요. 그리고 수의 경우에는 약간 예외적인데요, Integer.new라고 써주면 정수를 만들 수 있어요. 정수는 그냥 쓰기만 하면 되죠. (의미는?)

Because we can create arrays and strings using [...] and '...' respectively, we rarely create them using new. (Though it's not really obvious from the above example, String.new creates an empty string, and Array.new creates an empty array.) Also, numbers are special exceptions: you can't create an integer with Integer.new. You just have to write the integer.
 

시간과 관련된 클래스

Time Class라니, 이건 또 무슨 내용일까요? Time 객체는 시간과 관련된 것들을 다룹니다. 이 클래스를 사용하면 시간에다가 수를 더하거나 시간에서 수를 빼서 새로운 시간를 얻을 수 있습니다. 예를 들어 어떤 시간에다가 1.5를 더하면, 새로운 시간은 원래 시간에서 1.5초 후의 시간이 되지요. 다음의 예를 볼까요?

time  = Time.new   #  The moment I generated this web page.
time2 = time + 60  #  One minute later.

puts time
puts time2

#실행결과

Tue Apr 14 16:29:20 GMT 2009
Tue Apr 14 16:30:20 GMT 2009

Time.mktime을 사용해서, 특정한 순간을 가리키는 시간을 만들 수도 있습니다. mktime은 make time의 약자인 것 같네요.

puts Time.mktime(2000, 1, 1)          #  Y2K.
puts Time.mktime(1976, 8, 3, 10, 11)  #  내가 태어난 시간

#실행결과

Sat Jan 01 00:00:00 GMT 2000
Tue Aug 03 10:11:00 GMT 1976

주의 : 태평양 기준시(이부분 잘 몰겠음. )로 태어난 시간을 나타낸 거예요. 2000이 도래했을 때는 태평양 기준시(PST)를 기준으로 했죠. 적어도 서해안에 사는 우리들 입장에서는요(의미를 잘 모르겠음). 그리고 위에서 괄호를 써주는 이유는 mktime에 인자로 넘겨줄 매개변수들을 한 그룹으로 묶기 위해서입니다. 매개변수를 더 많이 추가할 수록, 시간은 더욱 정확해 지겠죠?

비교하는 메서드(comparison methods)를 사용하면 두 개의 시각을 비교할 수 있답니다. 이전 시각이 이후 시각보다 작다고 생각하시면 되요. 그리고 한 개의 시각에서 다른 시각을 빼주면, 이 두 시각 간의 초가 계산됩니다. 한 번 가지고 놀아 보세요!

Notice: that's when I was born in Pacific Daylight Savings Time (PDT). When Y2K struck, though, it was Pacific Standard Time (PST), at least to us West Coasters. The parentheses are to group the parameters to mktime together. The more parameters you add, the more accurate your time becomes.
You can compare times using the comparison methods (an earlier time is less than a later time), and if you subtract one time from another, you'll get the number of seconds between them. Play around with it!

프로그램 만들어보기

10억 초

여러분이 태어난 시각을 초단위로 정확하게 알아내보세요. (할 수 있다면요.) 여러분이 10억초 만큼 산 시점이 되는 시각(또는 이미 된 시각)을 구해보세요. 그리고 달력에다가 표시해 보세요.

생일 축하해요!

누군가에게 몇 년도에 태어났는지, 몇 월 몇 일에 태어났는지 물어보세요. 그 사람이 몇 살인지 알아내 보세요. 그리고 과거에 생일을 맞았던 횟수만큼 생일 빵을 해주세요!

해시 클래스에 대해 알아봅시다.

유용한 클래스가 또 하나 있는데요, 해쉬 클래스라고 합니다. 해쉬는 배열하고 많이 비슷해요. 해쉬에는 슬롯들이 많이 있고요, 이 슬롯들은 다양한 객체들을 가리킵니다. 하지만 배열의 경우, 슬롯은 한 줄로 늘어서 있고, 각 슬롯에 0에서 시작하는 번호가 매겨져 있죠. 반면에 해쉬에서는 슬롯들이 한 줄로 늘어서 있지 않습니다. 뭐랄까요, 서로 뒤섞여 있어요. 그리고 해쉬 안에 있는 슬롯을 가리키려면 배열처럼 번호를 쓰지 않고, 객체를 사용할 수 있어요. 추적해야 하는 것들인데, 정돈된 리스트에는 맞지 않는 것, 그런 것들이 많을 때에는 해쉬를 사용하는 것이 좋아요. 예를 들어, 이 튜토리얼에서 사용한 코드의 여러 종류를 표시하기 위해 사용하는 색깔들의 경우, 해쉬 클래스를 사용했어요.

colorArray = []  #  same as Array.new
colorHash  = {}  #  same as Hash.new

colorArray[0]         = 'red'
colorArray[1]         = 'green'
colorArray[2]         = 'blue'
colorHash['strings']  = 'red'
colorHash['numbers']  = 'green'
colorHash['keywords'] = 'blue'

colorArray.each do |color|
  puts color
end
colorHash.each do |codeType, color|
  puts codeType + ':  ' + color
end

#실행결과

red
green
blue
strings:  red
keywords:  blue
numbers:  green

배열을 사용하면, 0번 슬롯은 문자열표시용이고, 1번 슬롯은 숫자표시용이라는 것을 기억해야 하죠. 그런데 해쉬를 사용하면 쉽죠! 'strings' 슬롯은 문자열을 표시하는 색깔을 보관하고 있으니 기억해야 할 게 없죠. 그런데 위에서 아마도 이 점을 알아차리셨을 거예요. each를 사용했을 때, 해쉬 내에 있는 객체들은 처음에 해쉬 안에 집어넣은 순서대로 나오지 않았어요. 배열에서는 내부의 슬롯을 일정한 순서대로 보관하는 반면에 해쉬는 그렇지 않죠.

사람들은 보통 해쉬 안에 있는 슬롯의 이름으로 문자열을 사용합니다. 그런데 꼭 문자열이 아니더라도 다른 종류의 객체를 사용해도 되요. 심지어는 배열이나 다른 해쉬를 사용할 수도 있죠. (하지만 여러분이 그렇게 하고 싶어하리라고는 상상하기 어렵네요...):

weirdHash = Hash.new

weirdHash[12] = 'monkeys'
weirdHash[[]] = 'emptiness'
weirdHash[Time.new] = 'no time like the present'

해쉬가 더 편한 경우가 있고, 배열이 더 편한 경우도 있죠. 어떤 특정한 문제를 해결하기 위해 어느 쪽이 더 좋을지는 여러분이 결정하시면 됩니다.

클래스를 확장한다는 것

8장의 마지막 부분에서 여러분은 주어진 정수에 대해서 영어 문구를 만들어 주는 메서드를 만들었었죠. 그 메소드는 정수 메소드가 아니었습니다. 그 메소드는 generic "프로그램" 메소드였죠.

22.to_eng 이렇게 호출해서 숫자22를 문자열 ‘22’로 만들 수 있으면 좋지 않을까요? 그렇게 할 수 있는 방법을 알려 드릴게요.
 

class Integer
 
  def to_eng
    if self == 5
      english = 'five'
    else
      english = 'fifty-eight'
    end
    
    english
  end

end

#  I'd better test on a couple of numbers...
#제가 여러분이라면 몇몇 수를 가지고 테스트해 볼 거예요.

puts 5.to_eng
puts 58.to_eng

#실행결과

five
fifty-eight

흠, 테스트했더니, 잘 되는 것 같네요. ;)

자 이제 모든 정수들은 이 메소드를 가지게 되었어요. to_s같은 내장 함수가 작동하는 방식이 마음에 안드시면 위에서 한 것처럼 다시 정의를 해주시면 되요. 하지만 추천하지는 않습니다! 새로운 것을 하고 싶다면, 원래의 메소드는 그냥 두고, 새로운 메소드를 만들어서 쓰는 편이 좋습니다.

음.. 아직 헷갈리시다고요? 마지막 프로그램을 다시 한번 살펴 보죠. 이제까지 어떤 코드나 정의된 메소드를 실행했을 때마다, 우리는 기본 “프로그램" 오브젝트를 가지고 실행했어요. 그런데 마지막 프로그램에서는 그 기본 프로그램 오브젝트를 처음으로 벗어났어요. 그리고 Integer라는 클래스 안으로 들어갔죠. 우리는 Ingeter 클래스 안에서 메소드를 정의했죠.즉 이 메소드는 integer 클래스의 메소드가 되어고요. 이렇게 해서 모든 ingeter는 이 메소드를 쓸 수 있게 되었습니다. 이 메소드 안에서 우리는 self를 사용해서 이 메소드를 이용하고 있는 객체, 즉 integer를 가리킬 수 있죠.

클래스를 만들어 볼까요?

몇 몇 종류의 클래스 객체를 이제까지 접했습니다. 하지만 루비가 이미 가지고 있지 않은 종류의 객체가 필요한 경우도 많습니다. 다행히도 새로운 클래스를 만들어내는 것은 기존의 클래스를 확장하는 것만큼이나 쉽습니다. 루비로 주사위를 하나 만든다고 해봅시다. 주사위 클래스를 만드는 법이 다음에 나옵니다 :

class Die
 
  def roll
    1 + rand(6)
  end
 
end

#  Let's make a couple of dice...
dice = [Die.new, Die.new]

#  ...and roll them.
dice.each do |die|
  puts die.roll
end

#실행결과

3
4

(여러분이 임의의 수에 관한 부분을 건너뛰었을 경우를 위해 설명드리자면, rand(6)은 0과 5 사이에 있는 임의의 수를 반환합니다. 그게 전부예요. 사실 우리가 주사위 프로그램을 통해서 알아내려는 바로 그 수이지요.)

우리는 객체에 필요한 모든 종류의 메서드를 정의할 수 있습니다. 그런데 뭔가 빠진 것이 있어요. 이 객체를 다루는 것은 우리가 변수에 대해서 배우기 전에 프로그래밍하는 것과 훨씬 더 비슷해요. (응? 무슨 말이지?) 우리가 만든 주사위를 예로 살펴볼까요? 우리는 주사위를 굴릴 수도 있고, 매번 굴릴 때마다 주사위에는 다양한 수가 나오죠. 하지만 만약 주사위가 하나의 수만을 나타내기를 원한다면, 그 수를 가리키는 변수를 만들어야 할 거예요. 괜찮은 주사위라면 던졌을 때 임의의 수가 나와야 하고, 주사위를 던진다면 그 수가 바뀌어야 겠죠. 하지만 주사위가 표시한 수를 추적한다면, 주사위가 보이고 있는 수는 굳이 추적하지 않아도 될 거예요. (응? 내가 제대로 이해한 게 맞나??)

하지만, roll(roll이라는 객체) 안에서 지역 변수에다가 우리가 roll한 수(주사위를 던져서 얻어낸 수)를 저장하려고 한다면, roll(이라는 객체)가 소멸되자 마자 그 수는 없어질 거예요. 그래서 우리는 그 수는 다른 종류의 변수에다가 보관해야 하죠.

인스턴스 변수에 대해서 알아봅시다.

보통 문자열에 대해서 얘기하려고 할 때, 우리는 그것을 문자열이라고만 부릅니다. 하지만 그것을 문자열 객체라고 부를 수도 있어요. 그리고 프로그래머들은 가끔 그것을 문자열 클래스의 인스턴스라고도 부릅니다. 이렇게 부르더라도 결국 문자열이라는 의미에요. 길고 복잡하게 표현했을 뿐이죠. 클래스의 인스턴스라는 것은요, 그 클래스의 객체라는 것을 의미해요. 그래서 인스턴스 변수라고 하면, 객체의 변수라고 할 수 있죠. 메소드의 지역 변수는 메소드가 끝나기 전까지만 남아있어요.  하지만 객체의 인스턴스 변수는 객체가 존재하는 한 계속 남아있어요. 인스턴스 변수를 지역 변수와 구분해주기 위해, 인스턴스 변수의 경우에는 이름 앞에 @(골뱅이)가 붙습니다.
 

class Die
 
  def roll
    @numberShowing = 1 + rand(6)
  end
 
  def showing
    @numberShowing
  end
 
end

die = Die.new
die.roll
puts die.showing
puts die.showing
die.roll
puts die.showing
puts die.showing

#실행결과

1
1
5
5

잘 되는군요! roll 메소드는 주사위를 던지고요, showing 메소드는 어떤 수가 나왔는지 알려 줍니다. 하지만 주사위를 던지기 전에 나왔던 수가 무엇인지 알려면 어떻게 해야 할까요? (@numberShowing이라는 변수의 값을 넣기 전에 말에죠.)?

class Die
 
  def roll
    @numberShowing = 1 + rand(6)
  end
 
  def showing
    @numberShowing
  end
 
end

#  Since I'm not going to use this die again,
#  I don't need to save it in a variable.
puts Die.new.showing

#실행결과

nil

흠흠... 적어도 에러는 안 나왔군요. 하지만 아직도 주사위를 던진것을 취소한다는 것은 말이 안되는 것 같아요.(?? 의미를 제대로 이해했는지 확신이 안 섬..) 그리고 nil이 여기서 무엇을 의미하는 지도 모르겠고요. 주사위가 만들어지자 마자 이 새로운 주사위 객체에 몇 가지 값을 넣을 수 있으면 좋을 것 같습니다. 바로 이 때문에 initialize메소드를 쓰는 거예요.

class Die
 
  def initialize
    #  I'll just roll the die, though we
    #  could do something else if we wanted
    #  to, like setting the die with 6 showing.
    roll
  end
 
  def roll
    @numberShowing = 1 + rand(6)
  end
 
  def showing
    @numberShowing
  end
 
end

puts Die.new.showing

#실행결과

6

 initialize 메소드가 정의되어 있는 경우에는, 객체가 만들어질 때 이 initialize 메소드가 항상 호출됩니다. 우리가 만든 주사위는 거의 완벽하죠. 단 한가지 부족한 게 있다면 주사위를 던지기 전에 어떤 수가 나올지를 미리 정하는 방법이 없다는 점이에요. cheat 메소드(‘속이다' 메소드)를 만들어서 이런 기능을 구현하지 그래요?! 다 만들었다면 (그리고 잘 작동하는지도 테스트했다면) 원래 하던 얘기로 돌아갑시다. 한 가지만 확인하세요! 속일 때 속이더라도, 나오는 수가 7은 되지 않도록 해야 겠죠?

아까 우리가 살펴본 내용은 꽤 멋진 거예요. 좀 어렵긴 하지만요. 좀 더 재미있는 예를 들어볼게요. 가상의 애완동물을 만들어본다고 합니다. 새끼 용을 만들어볼게요. 다른 아기들이 그렇듯, 새끼 용은 먹고, 자고, 응가해야 합니다. 이 얘기는 우리가 이 새끼용을 먹여줘야 하고, 침대에 눕혀 줘야 하고, 산책도 시켜줘야 한다는 의미지요. 내부적으로 우리의 새끼 용은 배고픔, 피로도, 걸어야 하는 욕구에 대해 알고 있어야 합니다. 하지만 우리는 새끼 용의 이런 내부적인 상태에 대해서 알 수 없죠. 왜, 아기들에게 “아가야, 배고프니?”라고 물어볼 수 없잖아요? 새끼 용과 의사소통(상호작용? 예를 보고 선택해야)할 수 있는 몇 가지 재미있는 방법들을 추가할 거예요. 그리고 새끼 용이 태어날 때에는 이름도 지어 줄 거고요. (new라는 메소드에 넘겨준 것들은 모두 initialize 메소드로 전달됩니다.) 좋습니다, 이제 만들어 볼까요?

class Dragon
 
  def initialize name
    @name = name
    @asleep = false
    @stuffInBelly     = 10  #  He's full.
    @stuffInIntestine =  0  #  He doesn't need to go.
    
    puts @name + ' is born.'
  end
 
  def feed
    puts 'You feed ' + @name + '.'
    @stuffInBelly = 10
    passageOfTime
  end
 
  def walk
    puts 'You walk ' + @name + '.'
    @stuffInIntestine = 0
    passageOfTime
  end
 
  def putToBed
    puts 'You put ' + @name + ' to bed.'
    @asleep = true
    3.times do
      if @asleep
        passageOfTime
      end
      if @asleep
        puts @name + ' snores, filling the room with smoke.'
      end
    end
    if @asleep
      @asleep = false
      puts @name + ' wakes up slowly.'
    end
  end
 
  def toss
    puts 'You toss ' + @name + ' up into the air.'
    puts 'He giggles, which singes your eyebrows.'
    passageOfTime
  end
 
  def rock
    puts 'You rock ' + @name + ' gently.'
    @asleep = true
    puts 'He briefly dozes off...'
    passageOfTime
    if @asleep
      @asleep = false
      puts '...but wakes when you stop.'
    end
  end
 
  private
 
  #  "private" means that the methods defined here are
  #  methods internal to the object.  (You can feed
  #  your dragon, but you can't ask him if he's hungry.)
 
  def hungry?
    #  Method names can end with "?".
    #  Usually, we only do this if the method
    #  returns true or false, like this:
    @stuffInBelly <= 2
  end
 
  def poopy?
    @stuffInIntestine >= 8
  end
 
  def passageOfTime
    if @stuffInBelly > 0
      #  Move food from belly to intestine.
      @stuffInBelly     = @stuffInBelly     - 1
      @stuffInIntestine = @stuffInIntestine + 1
    else  #  Our dragon is starving!
      if @asleep
        @asleep = false
        puts 'He wakes up suddenly!'
      end
      puts @name + ' is starving!  In desperation, he ate YOU!'
      exit  #  This quits the program.
    end
    
    if @stuffInIntestine >= 10
      @stuffInIntestine = 0
      puts 'Whoops!  ' + @name + ' had an accident...'
    end
    
    if hungry?
      if @asleep
        @asleep = false
        puts 'He wakes up suddenly!'
      end
      puts @name + '\'s stomach grumbles...'
    end
    
    if poopy?
      if @asleep
        @asleep = false
        puts 'He wakes up suddenly!'
      end
      puts @name + ' does the potty dance...'
    end
  end
 
end

pet = Dragon.new 'Norbert'
pet.feed
pet.toss
pet.walk
pet.putToBed
pet.rock
pet.putToBed
pet.putToBed
pet.putToBed
pet.putToBed

#실행결과

Norbert is born.
You feed Norbert.
You toss Norbert up into the air.
He giggles, which singes your eyebrows.
You walk Norbert.
You put Norbert to bed.
Norbert snores, filling the room with smoke.
Norbert snores, filling the room with smoke.
Norbert snores, filling the room with smoke.
Norbert wakes up slowly.
You rock Norbert gently.
He briefly dozes off...
...but wakes when you stop.
You put Norbert to bed.
He wakes up suddenly!
Norbert's stomach grumbles...
You put Norbert to bed.
He wakes up suddenly!
Norbert's stomach grumbles...
You put Norbert to bed.
He wakes up suddenly!
Norbert's stomach grumbles...
Norbert does the potty dance...
You put Norbert to bed.
He wakes up suddenly!
Norbert is starving!  In desperation, he ate YOU!

야호! 물론 이 프로그램이 좀 더 인터렉티브한 방식이었다면 더 좋았겠지만, 그렇게 하는 것은 나중에 할 수 있어요. 저는 새로운 용 클래스가 만들어지는 것과 직접 관계되는 부분들을 보여드리고 싶었어요.

이번 예제에서는 몇 가지 새로운 것들을 알게 되었어요. 첫번째 것은 간단해요. exit을 호출하면 프로그램을 바로 그 시점에 그 지점에서 종료시켜요. 두번째는 private라는 거예요. 위에서 우리가 클래스 정의할 때 중간 쯤에 두었던 거예요. private를 안 쓸 수도 있지만, 

이것은 ‘덮개' 같은 거라고 생각해도 좋아요. 자동차 정비공이 아니라면, 자동차에 대해서 여러분이 알아야 하는 것은 엑셀과 브레이크 페달, 기어를 사용하는 방법 정도이겠죠. 프로그래머는 자동차라는 클래스에 대해서 public interface(??) 를 호출할 수 있죠. 에어백이 언제 부풀어야 하는지는 자동차 내부에서 알아서 일어나는 일이죠. 보통 사람은 운전을 하더라도 이런 것들을 알 필요는 없죠.

여기서 좀 더 나아가서 더 구체적인 예를 살펴볼까요? 자동차 게임에서 차를 재현해 내려면 어떻게 해야할까요? (실은 제가 지금 이런 일을 하고 있답니다.) 우선은, 인터페이스가 어떻게 되야 할지 생각해야겠죠? 이 말은 즉 차라는 객체에 대해서 게이머가 어떤 메서드를 호출할 수 있을지를 정해야 한다는 의미죠. 흠. 우선 페달을 밟거나 브레이크 페달을 밟을 수 있어야겠죠. 그리고 페달을 얼마나 세게 밟고 있는지를 알 수 있도록 해야해요. 페달을 깊숙히 밟는 거랑, 약간 스치듯 밟는 것과는 아주 큰 차이가 있죠. 또한 기어를 바꿀 수도 있어야 하고요, 바퀴를 얼마나 세게 돌리고 있는지도 알 수 있어야 해요. 좀 더 나아간다면 클러치를 사용하게 할 수도 있겠죠. 신호를 바꾸고, rocket launcher, afterburner, flux capacitor 등등도 달 수 있죠. 여러분이 어떤 자동차 게임을 만드느냐에 따라서 달라지겠죠? 자동차라는 객체의 내부에는 훨씬 더 많은 일을 처리해줘야 할 겁니다. 차에 또 필요한 것으로 기본적으로는 속도, 방향, 위치 등이 있겠고요. 이 값은 엑셀 페달, 브레이크 페달, 핸들 돌리기 등을 통해서 변해야 합니다. 당연히 게이머가 위치를 직접 정할 수는 없어야 하겠죠? 자동차 게임을 만드는 입장에서는 차가 미끄러졌는지, 상처를 입지는 않았는지, 점프를 했는지 등등의 데이터를 기록하고 싶을 겁니다. 이런 것들은 자동차라는 객체에서 내부에 있어야 하는 것들이죠.

프로그램 만들어보기

오렌지나무 클래스를 만들어 보세요.

이 클래스에는 나무의 키높이를 반환하는 height 메서드가 있어야 하고요, 한 해가 지날 때마다 나이테처럼 나무의 나이를 1만큼 증가시켜주는 oneYearPasses 메서드가 있어야 합니다.  매년 이 나무는 키가 더 자라고요, 오렌지 나무가 1년에 얼만큼 자라는지는 여러분이 상상하기 나름입니다. 그리고 여러분이 정한 몇 년이 지난 후에 오렌지 나무는 죽습니다. 처음 몇 년 동안은 오렌지가 열리지 않고요, 그 후에는 오렌지가 열리기 시작해요. 제가 알기로 좀 더 나이많은 오렌지 나무에 더 많은 오렌지가 열린다고 알고 있어요. 상식에 맞게 정해 보세요. 물론 오렌지의 수를 셀 수도 있어야 하고요(countTheOranges, 이 메서드는 나무에 달린 오렌지의 수를 반환합니다) 오렌지를 딸 수도 있어야 합니다(pickAnOrance, 이 메서드는 @orangeCount안에 들어있는 객체를 하나 없애주고 이 오렌지가 정말 맛있었다는 문자열을 보여주어야 합니다. 오렌지가 남아있지 않다면 올해에는 더 이상 오렌지가 남아있지 않다고 말해주어야 하고요.) 또 하나, 한 해에 따지 않고 남은 오렌지는 다음해가 되기 전에 다 떨어진다는 것을 잊지 마세요.

새끼 드래곤을 돌보는 프로그램을 만들어 보세요.

새끼 드래곤에게 먹이를 주거나 산책을 시킬 수 있는 메서드가 있어야 합니다. 그리고 새끼 드래곤에 대해 이 메서드를 호출할 수 있어야 하죠. 그리고 문자열을 입력할 수 있어야 하게 때문에, 메세지를 보낼 수 있는 메서드도 필요하답니다. 프로그램에 문자열을 입력하면, 적합한 메서드를 호출하도록 말이죠.

9장을 마무리하며

자! 프로그램에 대한 건 정말 다 배운 것 같군요.. 아참! 뭔가 아직 말씀드리지 않은 게 있군요. 이메일을 보내거나 컴퓨터에서 파일을 불러오거나 저장하는 프로그램, 아니면 윈도우 창이나 버튼, 온갖 3D로 만든 것들을 만들어주는 프로그램을 만드는데 필요한 클래스에 대한 얘기를 안해드렸네요. 쓸 수 있는 클래스는 정말 다양하답니다. 모든 클래스를 다 보여드릴 수는 없어요. 무슨 클래스가 있는지조차 다 모르죠! 다만 여러분에게 도움을 드릴 수 있는 것은, 이런 클래스에 대해서 어디서 찾을 수 있는지는 알려드릴 수 있어요. 그리고 그 클래스들을 가지고 프로그램을 만드는 법을 배우면 되죠. 여러분을 그 곳으로 보내드리기 전에, 딱 한가지 루비에 대해서 더 말씀드리고 싶은 것이 있어요. 대부분의 프로그래밍 언어에는 없는 것이죠. 저는 이것 없이는 못 살아요: 바로 블록과 프록이라고 불리는 것입니다.

참고

댓글

댓글 본문