반응형

루비는 모든것이 객체라고 했죠. 따라서 클래스는 매우 중요하겠죠. 객체지향 프로그램에 대해 여기서 주절주절 설명하는건 제 주제에도 넘은 짓이고 그렇게 간단하게 말할 수 있는게 아니기에 여기선 더 언급하지 않겠지만 클래스를 제대로 쓰기위해서는 객체지향 프로그래밍 방법을 제대로 익히는게 중요하다는걸 명심하시고 따로 수련해 두시길 부탁드립니다.

그리고 이부분도 irb로 시험해 볼 수도 있지만 불편한점이 있으므로 일반에디터로 파일을 작성해서 실행하는 방법으로 테스트 하는게 편하실 겁니다.

그럼 시작해보겠습니니다.

일단 클래스는 대충 이런 형태입니다.

class User
    def initialize(uid, name, ip)
        @uid = uid
        @name = name
        @ip = ip
    end
end  


클래스 이름은 대문자로 시작하고 함수명은 소문자로 시작해야 한다는것도 기억해 두시고요. initialize 라는 함수는 생성자 입니다. 객체가 생성될때 한번 실행되는 함수 입니다. 객체 생성시 초기화 작업이 필요하면 여기서 합니다.

일단 c언어 의 경우는 '{' 를 이용하고 python은 들여쓰기로 구분하지만 루비는 'end' 로 블럭을 만듭니다. def ~ end 로 클래스의 멤버함수를 만들죠.
변수앞에 @를 붙이는건 이 변수가 클래스의 멤버변수라는 표시입니다. 그러고 보니 설명하지 않은게 많네요. 다음기회에....

class User
    def initialize(uid, name, ip)
        @uid = uid
        @name = name
        @ip = ip
    end
    
    def printInfo()
        puts "ID = #{@uid} -- Name : #{@name}"
    end
end   

x = User.new("milk","john","000.000.000.000")
x.printInfo


위의 예제에 간단히 printInfo 라는 함수를 추가 했습니다.

그리고 객체 생성을 User.new 라는 방법으로 했죠. 생성자에 값도 넣어주고 말이죠.
x.printInfo 라는 부분을 보시면 아시겠지만 루비에선 넘기는 인자가 없으면 '(' 괄호는 사용하지 않아도 됩니다.

class User
    attr_reader :uid
    def initialize(uid, name, ip)
        @uid = uid
        @name = name
        @ip = ip
    end
    
    def printInfo()
        puts "ID = #{@uid} -- Name : #{@name}"
    end
end   

x = User.new("milk","john","000.000.000.000")
x.printInfo
puts "ID = #{x.uid}"
x.uid = "aaa"


추가된 부분이 보이시나요? 소스의 둘째 줄입니다. attr_reader 라는 문장이 보이시죠. 직접 변수에 대한 read 를 가능하게 해줍니다. 위 소스를 실행해 보면 결과는 이렇습니다.

ID = milk -- Name : john
ID = milk
user.rb:17: undefined method `uid=' for #<User:0x1d7b222> (NoMethodError)

읽기는 가능했지만 쓰기는 불가능 하네요. 쓰기 가능은 attr_writer 입니다.

다음은 클래스 변수와 클래스 함수 입니다.
간단히 이야기 하면 c++/java 의 static 과 비슷하다고 할 수 있겠습니다.

클래스 변수는 간단히 설명하면 이런겁니다.

class User
    @@usernum = 0
    attr_writer :uid
    def initialize(uid, name, ip)
        @uid = uid
        @name = name
        @ip = ip
        @@usernum+=1
    end
    def printUsernum()
        puts "Usernum = #{@@usernum}"
    end
end   

User.new("aaa","bbb","xx")
x = User.new("ccc","ddd","xx")
x.printUsernum


결과는

Usernum = 2


뭔지 아시겠나요? 간단히 말하자면 클래스끼리 공유하는 변수라고 할 수 있겠네요. @@usernum = 0 으로 만들어 주었고 0 값으로 초기화 시켜주었습니다. 그 후에 객체를 2번 생성했고 @@usernum 에 1을 더한 결과가 누적되어 @@usernum 변수 값이 2가 되었습니다.

멤버함수는

class User
    @@usernum = 0
    attr_writer :uid
    def initialize(uid, name, ip)
        @uid = uid
        @name = name
        @ip = ip
        @@usernum+=1
    end
    def printUsernum()
        puts "Usernum = #{@@usernum}"
    end
    
    def User.printClassname()
        puts "I'm User Class"
    end
end   

User.printClassname()

결과는

I'm User Class


뭐...이런겁니다. new 로 객체를 생성하지 않고 바로 쓸수 있는 함수...별거 아니죠.

public/private/protected 같은 접근 제한자들도 있는데 이거 설명은 안하겠습니다.....

마지막으로 클래스라면 빼놓을 수 없는 상속에 대해 이야기 하겠습니다

class User
    attr_writer :uid
    def initialize(uid, name, ip)
        @uid = uid
        @name = name
        @ip = ip
    end
   
    def printInfo()
        puts "ID = #{@uid} -- Name : #{@name}"
    end
end  

class ServiceUser < User

    def sendMessage(msg)
        puts "Message<#{@uid}> : #{msg}"
    end
   
end

su = ServiceUser.new("white","lily","123.456.678.123")
su.printInfo
su.sendMessage("Hello")


=begin
x = User.new("milk","john","000.000.000.000")
x.printInfo
puts "ID = #{x.uid}"
x.uid = "aaa"
=end


ID = white -- Name : lily
Message<white> : Hello

실행 결과는 위와 같습니다.

우선 '=begine' '=end' 블럭은 이전의 코드를 주석처리 한겁니다. 여러줄 주석은 저렇게 처리하시면 되고요. 주의할 점은 '=begin' 이나 '=end' 가 라인 맨 앞에 있어야 한다는 것입니다. 앞에 공백도 있으면 안됩니다.

User 클래스를 상속한 ServiceUser 란 클래스를 생성해 주었습니다. 별다르게 설명할 내용은 없네요.
참고로 루비는 다중상속이 안됩니다. 대신 모듈이란게 있는데 이것도 나중에 설명하도록 하겠습니다.


이상 마치겠습니다. 이번 객체부분은 사실 좀 부실한듯도 한데요. 다른 객체지향언어를 좀 써봤거나 조금은 안다는 가정하에 쓰여져서 그렇습니다. 때문에 루비만의 클래스 만드는 법에 치중한거고요.

객체지향 프로그램은 간단히 설명하기 어려운 만큼 죄송하지만 다른 문헌으로 철저히 공부해 주시길 부탁 드리겠습니다.

'프로그래밍 > ruby' 카테고리의 다른 글

루비정리> 4. Block  (0) 2009.06.29
루비 정리> 2. 제어문과 반복문  (0) 2009.06.18
루비 정리> 1. 자료형  (0) 2009.06.13
객체지향 스크립트 언어 루비.  (0) 2008.01.25

+ Recent posts