개요
이번 블로그에서는 Ruby에서 클래스가 무엇이며, 어떻게 다루는지에 대해서 설명합니다.
클래스
Ruby 언어에서 변수 등의 데이터는 모두 오브젝트입니다. 클래스는 이 오브젝트의 설계도와 같은 것입니다. Ruby에서는 이 클래스를 사용자가 직접 만들 수 도 있고, 필요에 따라서 여러 개의 클래스를 조합하여 사용할 수 있습니다.
Ruby와 같이 오브젝트를 기반으로 한 언어를 오브젝트 지향 언어(Object Oriented Program language)라고 합니다. OOP의 가장 큰 특징은 클래스가 상속을 할 수 있으며, 상속을 통해 다른 클래스가 가지고 있는 기능을 이어받아 사용할 수 있습니다. 또한 상속을 통해 이어받은 클래스의 메서드를 상속한 쪽에서 덮어쓸수 있습니다.(Override)
클래스의 내용을 기술하는 것을 ‘클래스를 정의한다’라고 합니다. 클래스 정의에는 class문을 사용합니다.
class Book
...
end
클래스에서 오브젝트를 생성하기 위해서는 new 메서드를 사용합니다.
book = Book.new
변수
클래스에서는 다양한 변수들을 사용할 수 있습니다. 클래스에서 사용할 수 있는 변수들에 대해서 알아봅시다.
인스턴스 변수
인스턴스 변수는 클래스 안에서 사용되는 글로벌 변수입니다. 변수명은 @
로 시작합니다.
class Book
def printTitle
puts @title
end
...
end
인스턴스 변수는 클래스로부터 생성된 오브젝트에서 메서드를 통해 참조할 수 있습니다. 오브젝트의 외부에서 직접 참조하거나 대입할 수 없습니다.
class Book
def initialize
@title = 'Ruby'
end
def printTitle
puts @title
end
end
book = Book.new
book.printTitle
# Ruby
클래스 변수
클래스 변수는 클래스에서 공통으로 사용하는 변수입니다. 클래스 변수는 같은 클래스로부터 생성된 모든 오브젝트에서 공유하는 변수로, 변수명이 @@
로 시작합니다.
class Book
@@publisher = 'dev-yakuza'
def printPublisher
puts @@publisher
end
end
book = Book.new
book.publisher
# dev-yakuza
클래스 변수는 클래스를 정의할 때 직접 초기화할 수 있습니다. 클래스 변수는 클래스 안의 메서드를 통해 참조할 수 있으며, 클래스의 밖에서는 직접 참조할 수 없습니다.
상수
클래스 안에서는 상수를 정의할 수 있는데, 상수는 알파벳 대문자로 시작합니다.
class Book
Language = 'EN'
end
상수는 다음과 같이 클래스 외부에서 직접 참조할 수 있습니다.
puts Book::Language
클래스 변수와 상수는 비슷하지만 클래스 변수는 다시 대입할 수 있습니다.
class Counter
@@count = 0
def plus
@@count += 1
end
def printCount
puts @@count
end
end
counter = Counter.new
counter.plus
counter.printCount
# 1
메서드
클래스의 메서드에는 인스턴스 메서드와 클래스 메서드가 있습니다. 이 두 메서드에 대해서 알아봅시다.
인스턴스 메서드
인스턴스 메서드는 일반적인 메서드로, 오브젝트를 이용하여 메서드를 호출합니다.
class Greeting
def initialize
@name = 'World'
end
def hello
puts 'Hello ' + @name
end
end
greeting = Greeting.new
greeting.hello
# Hello World
클래스 메서드
클래스 메서드는 오브젝트에 의존하지 않는 처리를 정의할 때 사용되며, 클래스를 사용하여 메서드를 호출합니다.
class Greeting
@@name = 'World'
def Greeting.hello
puts 'Hello ' + @@name
end
end
Greeting.hello
# Hello World
클래스 메서드는 클래스를 사용하여 호출하므로, 인스턴스가 생성될 때, 생성되는 인스턴스 변수를 사용할 수 없습니다.
오브젝트 초기화
정의한 클래스의 오브젝트를 초기화하기 위해서는 initialize
메서드를 사용합니다.
class Book
def initialize
@title = 'Ruby'
end
def printTitle
puts @title
end
end
initialize 메서드는 new 메서드로 새로운 오브젝트를 생성할 때 자동으로 호출됩니다.
class Book
def initialize (author)
@author = author
end
def printAuthor
puts @author
end
end
book = Book.new('dev-yakuza')
book.printAuthor
# dev-yakuza
위와 같이 new 메서드를 사용하여 initialize 함수에 파라메터를 전달하여 초기화할 수 있습니다.
액세서
오브젝트의 밖에서 인스턴스 변수에 접근하는 방법에는 메스드 이외에도 액세서(Accessor)가 있습니다. attr_reader
, attr_writer
, attr_accessor
를 사용하여 액세서를 정의할 수 있습니다.
class Book
def initialize
@title = 'Ruby'
end
attr_accessor :title
end
book = Book.new
puts book.title # Ruby
book.title = 'Rails'
puts book.title # Rails
상속
OOP 언어에서 어떤 오브젝트가 다른 오브젝트의 특성을 이어받을 수 있으며, 이를 상속이라고 부릅니다.
클래스의 상속
클래스의 상속은 미리 정의되어 있는 클래스의 기능을 확대하거나 제한하여 새로운 클래스를 만드는 것을 말하며, 상속의 대상이 되는 클래스를 슈퍼 클래스(Super Class)
, 상속을 받아서 새롭게 만드는 클래스를 서브 클래스(Sub Class)
라고 합니다.
class [Sub Class] < [Super Class]
...
end
다음과 같이 클래스의 상속을 사용할 수 있습니다.
class Fruits
def fruits
puts "It's a Fruits"
end
end
class Apple < Fruits
def apple
puts "It's an Apple"
end
end
apple = Apple.new
apple.fruits # It's a Fruits
apple.apple # It's an Apple
위와 같이 Apple
클래스에는 fruits
메서드가 존재하지 않지만, 슈퍼 클래스로부터 상속받았기 때문에, fruits
메서드를 사용할 수 있습니다. 또한, 다음과 같이 슈퍼 클래스를 상속하여 생성한 서브 클래스를 다시 상속한 서브 클래스를 생성할 수 있습니다.
class Fruits
def fruits
puts "It's a Fruits"
end
end
class Apple < Fruits
def apple
puts "It's an Apple"
end
end
class Pie < Apple
def pie
puts "It's a Pie"
end
end
pie = Pie.new
pie.fruits # It's a Fruits
pie.apple # It's an Apple
pie.pie # It's a Pie
서브 클래스로부터 상속 받아 새로운 서브 클래스를 만들 때에는, 2개 이상의 클래스로부터 상속 받아 생성할 수 없습니다.
오버라이드
슈퍼 클래스의 메서드를 서브 클래스에서 다시 정의하는 것을 메서드의 오버라이드(Override)라고 합니다.
class Fruits
def name
puts "It's a Fruits"
end
end
class Apple < Fruits
def name
puts "It's an Apple"
end
end
apple = Apple.new
apple.name # It's an Apple
액세스 한정자
클래스의 메서드에 액세스 한정자(Access Modifier)를 사용하여 메서드의 액세스를 제한할 수 있습니다. 액세스 한정자에는 public
, private
, protected
가 있으며, 액세스 한정자를 지정하지 않는 경우 모두 public
이 됩니다.
class Book
def protectedTest
puts "this is a protected function"
end
protected :protectedTest
def publicTest
puts "this is a publicTest"
end
end
book = Book.new
book.publicTest # this is a publicTest
book.protectedTest # protected method `protectedTest' called for #<Book:0x00007f8c6d88ebd0> (NoMethodError)
액세스 한정자는 다음과 같은 특징이 있습니다.
액세스 한정자 | 설명 |
---|---|
public | 제한 없이 호출할 수 있다. |
private | 호출할 수 없다. |
protected | 호출할 수 없다. 단, 메서드가 소속된 오브젝트에서는 호출할 수 있다. |
class Book
def privateTest
puts "this is a private function"
end
private :privateTest
def protectedTest
puts "this is a protected function"
end
protected :protectedTest
def publicTest
puts "this is a publicTest"
protectedTest
privateTest
self.protectedTest
self.privateTest
end
end
book = Book.new
book.publicTest
# this is a publicTest
# this is a protected function
# this is a private function
# this is a protected function
# private method `privateTest' called for #<Book:0x00007fa2d9066a98> (NoMethodError)
특이 클래스 정의
특이 클래스 정의란 특정 오브젝트에 메서드나 인스턴스 변수를 추가하는 것을 의미합니다.
class Book
def initialize
@title = 'Ruby'
@author = 'dev-yakuza'
end
def printTitle
puts @title
end
end
book = Book.new
class << book
def printAll
puts @title + ' / ' + @author
end
end
book.printAll
# Ruby / dev-yak
def book.printAuthor
puts 'Author: ' + @author
end
book.printAuthor
# Author: dev-yakuza
클래스 분할 정의
Ruby에서는 클래스를 분할하여 정의할 수 있습니다.
class Book
def initialize
@title = 'Ruby'
@author = 'dev-yakuza'
end
def printTitle
puts @title
end
end
class Book
def printAuthor
puts @author
end
end
book = Book.new
book.printTitle # Ruby
book.printAuthor # dev-yakuza
나중에 정의한 클래스의 메서드는 그대로 클래스에 추가되며, 같은 메서드가 있는 경우, 기존의 메서드는 제거되고 새로운 메서드가 추가됩니다.
class Book
def initialize
@title = 'Ruby'
@author = 'dev-yakuza'
end
def printTitle
puts @title
end
end
class Book
def printTitle
puts 'title: ' + @title
end
end
book = Book.new
book.printTitle # title: Ruby
완료
이것으로 OOP언어인 Ruby에서 클래스와 상속에 관해서 알아보았습니다. Ruby는 OOP언어이므로 클래스를 자주 사용합니다. 그러므로 이번 블로그 포스트에 나와있는 클래스를 잘 기억해둡시다.
제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!
앱 홍보
Deku
가 개발한 앱을 한번 사용해보세요.Deku
가 개발한 앱은 Flutter로 개발되었습니다.관심있으신 분들은 앱을 다운로드하여 사용해 주시면 정말 감사하겠습니다.