덕 타이핑
Coddy Ruby 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 33번째.
Ruby는 메서드를 호출하기 전에 객체의 클래스를 확인하지 않습니다. 객체에 해당 메서드가 있기만 하면 됩니다. "오리처럼 걷고 오리처럼 꽥꽥거리면, 그것은 오리입니다." 이것이 덕 타이핑입니다. 공통 슈퍼클래스를 전혀 공유하지 않는 클래스들도 같은 위치에서 사용할 수 있습니다:
class Duck
def speak
"Quack"
end
end
class Robot
def speak
"Beep"
end
end
class Radio
def speak
"...news..."
end
end
[Duck.new, Robot.new, Radio.new].each { |thing| puts thing.speak }출력:
Quack
Beep
...news...내장 클래스도 함께 참여합니다. <<만 사용하는 메서드는 배열, 문자열 또는 <<를 정의한 여러분의 어떤 객체와도 작동합니다:
class Tally
attr_reader :count
def initialize
@count = 0
end
def <<(_item)
@count += 1
self
end
end
def export(items, target)
items.each { |item| target << item.to_s }
target
end
p export([1, 2], [])
p export([1, 2], +"")
puts export([1, 2, 3], Tally.new).count출력:
["1", "2"]
"12"
3respond_to?(:name)은 객체를 호출하지 않고 객체에 공개 메서드가 있는지 묻습니다. 객체가 선택적 기능을 지원할 수도 있고 지원하지 않을 수도 있을 때 사용하세요:
class Printer
def print_page(text)
"printing #{text}"
end
end
class Scanner
end
[Printer.new, Scanner.new].each do |device|
if device.respond_to?(:print_page)
puts device.print_page("report")
else
puts "#{device.class} cannot print"
end
end출력:
printing report
Scanner cannot print객체에 해당 메서드가 없으면 호출 시 NoMethodError가 발생하며, 그 메시지에는 메서드와 객체의 이름이 표시됩니다. 덕 타이핑은 전달된 모든 객체가 자신에게 전송된 메서드에 응답한다는 점에 의존합니다:
def loudest(things)
things.map(&:speak).max_by(&:size)
end
class Cat
def speak
"Meow"
end
end
puts loudest([Cat.new, Cat.new])
begin
loudest([Cat.new, 42])
rescue NoMethodError => e
puts e.message
end출력:
Meow
undefined method `speak' for an instance of Integer챌린지
쉬움Printer 및 LineCounter 클래스와 functions.rb의 헬퍼 export(items, target)를 완성하세요. export는 target << item.to_s를 사용하여 모든 항목을 대상에 보내고 대상을 반환합니다. Printer#<<는 줄 번호와 함께 1: text 형식으로 텍스트를 출력하고 프린터를 반환합니다. LineCounter#<<는 줄 수와 문자 수를 세고 카운터를 반환하며, 해당 to_s는 3 lines, 12 chars를 반환합니다.
제공된 코드는 항목을 읽어 배열로 내보내고(p로 출력), 새 문자열로 내보내며(p로 출력), Printer와 LineCounter로 내보냅니다(puts로 출력).
코드는 printer.rb, line_counter.rb 및 functions.rb에 작성하세요. main.rb에는 제공된 입력/출력 코드가 있으며 편집할 수 없습니다.
직접 해보기
require_relative 'printer'
require_relative 'line_counter'
require_relative 'functions'
# 제공된 입력/출력 코드: 그대로 유지하세요
input = []
while (line = gets)
input << line.chomp
end
p export(input, [])
p export(input, +"")
export(input, Printer.new)
puts export(input, LineCounter.new)
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 Ruby 컴파일러