클래스 정의는 다음의 양식을 띕니다. (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 메소드는 오직 현재 객체에서만 접근 가능합니다. 같은 클래스의 다른 객체에서도 접근이 불가능합니다.
def method1 #기본값은 public입니다.
end
protected #이하 정의되는 메소드는 protected 접근을 가집니다.
def method2
end
...
private #이하 정의되는 메소드는 private 접근을 가집니다.
...
public
...
end
또는 다음과 같이 정의할 수 있습니다.
class MyClass
...
public :method1, :method2
protected :method3
private :method4
end
변수는 값을 저장하는게 아니라 레퍼런스(참조)를 저장하고 있다. (Java와 동일)
왠지 Effective XX 시리즈 냄새가 나는데???
답글삭제@옥똥 - 2007/05/11 13:02
답글삭제아닌뎅.. Pragmatic 시리즈삼(인사이트에서 번역)