모듈과 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챌린지
쉬움모듈과 클래스를 완성하세요. 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)}"
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 Ruby 컴파일러