Menu
Coddy logo textTech

모듈과 include

Coddy Ruby 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 27번째.

모듈은 이름이 지정된 메서드 그룹입니다. 모듈은 객체를 생성할 수 없지만, 클래스가 모듈을 include할 수 있으며, 그러면 모든 인스턴스가 마치 해당 클래스가 메서드를 정의한 것처럼 모듈의 메서드를 갖게 됩니다. 이를 믹스인이라고 합니다:

module Greetable
  def greet
    "Hello, I am #{name}"
  end
end

class Person
  include Greetable
  attr_reader :name

  def initialize(name)
    @name = name
  end
end

puts Person.new("Ada").greet

출력:

Hello, I am Ada

모듈의 메서드는 위의 name과 같이 클래스가 제공하는 메서드를 호출할 수 있습니다. 따라서 각 클래스가 모듈에서 사용하는 것을 제공하기만 한다면 하나의 모듈이 서로 매우 다른 클래스에도 사용될 수 있습니다:

module Greetable
  def greet
    "Hello, I am #{name}"
  end
end

class Robot
  include Greetable

  def name
    "R2"
  end
end

class City
  include Greetable

  def name
    "Paris"
  end
end

puts Robot.new.greet
puts City.new.greet

출력:

Hello, I am R2
Hello, I am Paris

클래스에는 슈퍼클래스가 하나만 있지만 모듈은 얼마든지 포함할 수 있습니다. include?는 클래스가 모듈을 포함하는지 묻고, 모듈은 ancestors에 클래스 바로 다음에 나타납니다. Ruby는 이 순서에서 메서드를 찾습니다:

module Swimmer
  def swim
    "swimming"
  end
end

module Flyer
  def fly
    "flying"
  end
end

class Duck
  include Swimmer
  include Flyer
end

d = Duck.new
puts "#{d.swim}, #{d.fly}"
puts Duck.include?(Flyer)
p Duck.ancestors.take(3)

출력:

swimming, flying
true
[Duck, Flyer, Swimmer]

모듈은 관련된 클래스와 상수를 하나의 이름인 네임스페이스 아래에 함께 묶어 이름이 충돌하지 않도록 하기도 합니다. Shop::Item과 Game::Item은 서로 다른 클래스입니다.

module Shop
  TAX = 0.2

  class Item
    def label
      "shop item, tax #{TAX}"
    end
  end
end

puts Shop::Item.new.label
puts Shop::TAX

출력:

shop item, tax 0.2
0.2
challenge icon

챌린지

쉬움

모듈과 클래스를 완성하세요. Greetable#greet는 객체의 name을 사용하여 Hello, I am Ada를 반환합니다. Walkable#walk(steps)는 @steps에 저장된 카운터에 걸음 수를 더하고(처음에는 nil에서 시작) 누적 합계인 Ada walked 30 steps를 반환합니다. Person은 두 모듈을 모두 포함하고, Robot은 Greetable만 포함하며 이름은 일련 번호 앞에 R-가 붙은 형태입니다.

제공된 코드는 첫 번째 줄(Ada 7)에서 사람과 로봇을 만든 다음, greet p, greet r 또는 walk 10(사람에 대해) 명령을 실행하고 각 결과를 출력하며, 마지막으로 robot walks: false를 출력합니다.

작성한 코드는 greetable.rb, walkable.rb, person.rb 및 robot.rb에 들어갑니다. main.rb에는 제공된 입력/출력 코드가 있으며 편집할 수 없습니다.

직접 해보기

require_relative 'greetable'
require_relative 'walkable'
require_relative 'person'
require_relative 'robot'

# 제공된 입력/출력 코드: 그대로 유지하세요
input = []
while (line = gets)
  input << line.chomp
end
name, serial = input[0].split
person = Person.new(name)
robot = Robot.new(serial)
input.drop(1).each do |line|
  command, arg = line.split
  if command == "walk"
    puts person.walk(arg.to_i)
  else
    target = arg == "p" ? person : robot
    puts target.greet
  end
end
puts "robot walks: #{Robot.include?(Walkable)}"
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Ruby 컴파일러