Ruby의 클래스

2020-12-16 hit count image

Ruby에서 클래스가 무엇인지 어떻게 다루는지에 대해서 살펴봅니다.

개요

이번 블로그에서는 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언어이므로 클래스를 자주 사용합니다. 그러므로 이번 블로그 포스트에 나와있는 클래스를 잘 기억해둡시다.

제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!

앱 홍보

책 홍보

블로그를 운영하면서 좋은 기회가 생겨 책을 출판하게 되었습니다.

아래 링크를 통해 제가 쓴 책을 구매하실 수 있습니다.
많은 분들에게 도움이 되면 좋겠네요.

스무디 한 잔 마시며 끝내는 React Native, 비제이퍼블릭
스무디 한 잔 마시며 끝내는 리액트 + TDD, 비제이퍼블릭
[심통]현장에서 바로 써먹는 리액트 with 타입스크립트 : 리액트와 스토리북으로 배우는 컴포넌트 주도 개발, 심통
Posts