2008년 01월 17일
기본 문법 - 클래스와 객체
10. 클래스와 객체
class Person
def initialize(name, age)
@name = name
@age = age
end
def name
return @name
end
def age
return @age
end
end
첫째줄에서 class Person부분은 Person 클래스 정의의 시작을 알리고 있다.
그 다음의 def initialize(name,age)… end 부분은 initialize 메소드의 정의이다. initialize는 객체를 초기화하는 메소드로 객체가 처음 생성될 때 자동으로 호출된다. initialize 메소드는 자바에서의 생성자 메소드와 비슷한 역할을 한다.
위의 initialize 메소드에서는 name와 age 두 개의 인자를 받아 각각 @name과 @age 변수에 지정해주고 있다. 변수 이름이 @로 시작하면 변수가 인스턴스 변수임을 의미하는데, 인스턴스 변수란 객체 자체의 데이터를 구성하는 방식이다. 즉 initialize는 외부에서 인자를 넘겨받아 객체 데이터를 초기화시켜주는 메소드인 것이다. 클래스의 new 메소드를 호출할 때 인자를 지정하면, 이 인자는 자동으로 initialize 메소드에 넘겨지게 된다.
def name… end 와 def age … end 는 일반적인 메소드 정의이다. name은 단순히 @name 을 리턴하는 메소드이고, age는 @age 를 리턴하는 메소드이다. 이들 메소드는 Person 객체에서 호출할 수 있다.
※ 루비의 인스턴스 변수는 객체 외부에서 직접 접근하는 것이 불가능하다. 따라서 외부에서 인스턴스 변수에 접근이 필요하다면, 이를 위한 접근자(Accessor) 메소드를 정의해야만 한다.
>> p = Person.new(“Tanaka”, 30)
=> #<Person:0x31a8c24 @age=30, @name=”Tanaka”>
여기에서는 Person 클래스의 new 메소드를 호출하면서 Tanaka 와 30 을 인자로 넘겨주고 있다. new 메소드는 객체를 생성한 직후에 객체의 initialize 메소드를 호출하면서 이들을 다시 인자로 넘겨준다. 이때 initialize 메소드는 Tanaka 와 30 을 각각 @name과 @age 객체변수에 지정하게 된다.
#<Person:0x31a8c24 @age=30, @name=”Tanaka”>는 생성된 Person 객체를 나타내고 있다.
>> p.name
=> “Tanaka”
>> p.age
=> 30
다시 정리하면, p는 Person 객체(데이터)이고, name과 age는 이 객체의 메소드이며, Person은 이 객체의 클래스이다. 또한 Person 객체의 데이터는 @name, @age 인스턴스 변수로 구성되고 있다.
루비의 메소드는 보통 객체에 묶여있지만, 클래스에 메소드를 묶어두는 것도 가능하다. 클래스 메소드는 클래스에 직접 호출하게 되는데, 시간(Time) 클래스의 now 나 Person 클래스의 new 와 같은 메소드가 바로 클래스 메소드이다. 클래스 메소드는 클래스를 정의할 때 메소드의 이름 앞에 self.를 붙여 정의한다.
class Fruit
def self.apple
return Fruit.new(“Apple”)
end
def self.banana
return Fruit.new(“Banana”)
end
def initialize (name)
@name = name
end
def name
return @name
end
end
위에서 apple 메소드와 banana 메소드는 클래스에 직접 호출되어, 각각 이름(name)이 “Apple”인 객체와 “Banana”인 객체를 리턴하고 있다. 이처럼 자주 쓰일만한 객체를 한 번에 생성해주는 것은 클래스 메소드가 활용되는 여러 용도 중의 하나이다.
루비에서는 클래스 간에 상속(Inheritance)을 가능하게 하고 있는데, 상속이란 한 클래스가 다른 클래스로부터 메소드를 물려받는 행위를 말한다. 예를 들어 직장인(Employee) 클래스와 학생(Student)클래스가 필요하다면, 이 둘의 공통적인 메소드를 묶어내어 사람(Person) 클래스에 집어 넣은 다음, Employee 클래스와 Student 클래스를 Person 클래스로부터 상속받게 할 수 있다.
class Employee < Person
def initialize (name, age, salary)
@name = name
@age = age
@salary = salary
end
def salary
@salary
end
def salary =(value)
@salary = value
end
end
위 코드에서 Employee < Person 부분은 Employee 클래스가 Person 클래스로부터 상속받는다는 것을 의미한다. Employee 클래스는 Person 클래스의 모든 메소드를 물려받게 되며, Employee 클래스에서 새로 추가된 메소드 역시 포함하게 된다.
위에서는 initialize 메소드가 재정의되고, salary 와 salary= 메소드가 추가되어 있는 것을 알 수 있다. 루비의 메소드는 마지막 줄의 코드가 리턴하는 값을 자동으로 리턴하기 때문에 위의 salary 메소드에서처럼 return을 생략해도 된다.
salary= 메소드는 다소 특별한 메소드인데, 이처럼 이름이 = 로 끝나는 메소드는 다음과 같은 방법으로 메소드를 호출하는 것이 가능하다.
emp.salary = 1800000
위 코드는 다음과 완전히 동일하게 취급된다.
emp.salary = (1800000)
이제 실제로 위의 정의를 irb에 입력하여, Employee 클래스를 사용해보자.
class Employee < Person
def initialize (name, age, salary)
@name = name
@age = age
@salary = salary
end
def salary
@salary
end
end
>>emp = Employee.new("Tanaka", 30, 1500000)
=> #<Employee:0x31a80d0 @age=30, @salary=1500000, @name=”Tanaka”>
>>emp.name
=> “Tanaka”
>>emp.salary
=> 1500000
>>emp
=> #<Employee:0x31a80d0 @age=30, @salary=1500000, @name=”Tanaka”>
Employee 클래스 자체에는 name 메소드가 정의되어 있지 않지만, Person 클래스의 name 메소드가 Employee 클래스로 상속되었기 때문에 위와 같은 사용이 가능하다. 위의 코드는 salary= 메소드를 사용하여 @salary 객체 변수를 업데이트하는 것 또한 보여주고 있다.
이처럼 클래스의 상속 기능은 여러 클래스의 공통된 기능을 별도 클래스로 묶어낼 수 있게 해줌으로써, 코드의 중복을 줄여준다.
이 글은 스프링노트에서 작성되었습니다.
# by | 2008/01/17 16:27 | Ruby on Rails | 트랙백


