2007년 5월 1일 화요일

3장 클래스,객체,변수

  클래스
클래스 정의는 다음의 양식을 띕니다. (Object에서 상속)
class ClassName
    # 생성자
        def initialize(param)
            @name = name     #인스턴스 변수 앞에는 @를 사용한다.
            ....
        end

    # 기본제공, 객체의 ID와 인스턴스 변수를 출력
    def inspect
       ...
    end

    # obj를 나타내는 string을 리턴
    def to_s
       ...
    end
end

  상속과 메시지
상속은 < 기호를 사용합니다.
class SubClassName < SuperClassName
    def initialize(param)
       # 부모 초기화
       super(param)
       ...
    end
   
    # super의 사용 예
    def to_s
      super + ""
    end
end

- SubClass에서 메소드가 없는 경우 부모를 따라가며 해당하는 메소드를 찾습니다.
- 메소드 내에서 super 키워드를 매개변수 없이 호출하면, 현재 객체의 부모의 메소드 중 동일한 이름의 메소드를 호출하도록 요청한다. 때로는 현재 메소드 호출에 전달된 매개변수를 호출하도록 요청합니다.
- 루비 객체의 최상위 부모는 Object이다. Object에는 to_s를 비롯한 몇 개의 메소드를 정의하고 있습니다.

 객체와 속성
외부에서 객체의 상태에 접근하고 이를 다루는 메소드를 속성(attribute)라고 부릅니다.
Song 클래스의 name 접근 메소드를 정의한다면 다음과 같이 정의할 수 있습니다.
class Song
   def name
      @name
   end
end

song = Song.new()
puts song.name

접근 메소드를 attr_reader를 사용하여 쉽게 정의할 수 있습니다. 사용법은 위의 접근 메소드와 동일합니다.
class Song
   attr_reader :name
end

  쓰기 가능한 속성
쓰기 가능한 속성의 정의는 다음과 같습니다.
class Song
   def duration=(new_duration)
      @duration = new_duration
   end
end

song = Song.new()
song.duration = 300

attr_reader처럼 attr_writer를 사용해서도 쉽게 정의할 수 있습니다.
class Song
   attr_writer :duration
end

  가상의 속성
속성이 꼭 인스턴스 변수로 존재할 필요는 없습니다. 가상으로 정의가 가능합니다.
class Song
   def duration_in_minutes
      @duration/60.0
   end
   def duration_in_minutes=(new_duration)
      @duration = (new_duration*60).to_i
   end
위의 코드 정의를 보면 song.duration_in_minutes라는 변수를 사용할 수 있지만, 실제로는 변수가 정의되어 있지는 않습니다.

  클래스 변수와 클래스 메서드
클래스 변수(@@name처럼 @두 개를 사용하여 정의)는 그 클래스의 모든 객체가 공유하며, 클래스 메서드에 의해서만 접근할 수 있습니다.

class MyLogger
   private_class_method : new

   # 클래스 변수는 사용하기 전에 반드시 초기화되어야 합니다.
   @@logger = nil

   # 클래스 메서드의 정의는 클래스이름.메소드이름으로 정의합니다.
   def MyLogger.create
      @@logger = new unless @@logger
      @@logger
   end
end
위의 코드대로 정의하는 경우 new를 사용하여 클래스를 생성할 수 없고, MyLogger.create를 사용해서만 클래스를 생성할 수 있게 됩니다.(싱글턴 패턴)

  접근제어
접근에 대해서 설정할 수 있는 속성은 세가지가 있습니다.
  • Public 메소드 - 아무런 접근 제어를 하지 않습니다.
  • Protected 메소드 - 그 객체를 정의한 클래스와 그 하위 클래스에서만 접근할 수 있습니다.
  • Private 메소드 - private 메소드는 오직 현재 객체에서만 접근 가능합니다. 같은 클래스의 다른 객체에서도 접근이 불가능합니다.
class MyClass
   def method1     #기본값은 public입니다.
   end
protected      #이하 정의되는 메소드는 protected 접근을 가집니다.
   def method2
   end
   ...
private     #이하 정의되는 메소드는 private 접근을 가집니다.
   ...
public
   ...
end

또는 다음과 같이 정의할 수 있습니다.
class MyClass
   ...
   public :method1, :method2
   protected :method3
   private :method4
end

변수는 값을 저장하는게 아니라 레퍼런스(참조)를 저장하고 있다. (Java와 동일)

댓글 2개:

  1. 왠지 Effective XX 시리즈 냄새가 나는데???

    답글삭제
  2. @옥똥 - 2007/05/11 13:02
    아닌뎅.. Pragmatic 시리즈삼(인사이트에서 번역)

    답글삭제