Ördek Tiplemesi
Coddy'nin Ruby Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 33 / 57.
Ruby bir yöntemi çağırmadan önce nesnenin sınıfını kontrol etmez; nesnenin yalnızca bu yönteme sahip olması yeterlidir. "Ördek gibi yürüyüp ördek gibi vaklıyorsa, o bir ördektir." Bu, ördek tiplemesidir: ortak bir üst sınıfı olmayan sınıflar yine de aynı yerde kullanılabilir:
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 }Çıktı:
Quack
Beep
...news...Yerleşik sınıflar da buna katılır. Yalnızca << kullanan bir yöntem; bir diziyle, bir metin dizisiyle veya << tanımlayan kendi nesnelerinizden herhangi biriyle çalışır:
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Çıktı:
["1", "2"]
"12"
3respond_to?(:name) bir nesnenin, onu çağırmadan genel erişimli bir yönteme sahip olup olmadığını sorar. Bir nesnenin isteğe bağlı bir özelliği destekleyip desteklemeyebileceği durumlarda bunu kullanın:
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Çıktı:
printing report
Scanner cannot printNesnede yöntem yoksa çağrı, yöntem ile nesnenin adını veren bir iletiye sahip olan NoMethodError hatasını oluşturur. Ördek tiplemesi, kendisine geçirilen her nesnenin gönderilen yöntemleri yanıtlayabilmesine dayanır:
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Çıktı:
Meow
undefined method `speak' for an instance of IntegerGörev
KolayTamamlayıcı sınıflar olan Printer ve LineCounter ile yardımcı export(items, target) işlevini functions.rb içinde tamamla. export, her öğeyi target << item.to_s ile hedefe gönderir ve hedefi döndürür. Printer#<<, metni satır numarasıyla birlikte 1: text biçiminde yazdırır ve yazıcıyı döndürür. LineCounter#<<, satırları ve karakterleri sayar ve sayacı döndürür; to_s ise 3 lines, 12 chars döndürür.
Sağlanan kod öğeleri okur ve bunları bir diziye (p ile yazdırılır), yeni bir dizeye (p ile yazdırılır), bir Printer nesnesine ve bir LineCounter nesnesine (puts ile yazdırılır) aktarır.
Kodun printer.rb, line_counter.rb ve functions.rb dosyalarına yazılır. main.rb, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
require_relative 'printer'
require_relative 'line_counter'
require_relative 'functions'
# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
input = []
while (line = gets)
input << line.chomp
end
p export(input, [])
p export(input, +"")
export(input, Printer.new)
puts export(input, LineCounter.new)
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Sınıflar ve Nesneler
Dosyalarla ÇalışmaSınıf TanımlamaÖrnek DeğişkenleriMetotlar ve selfto_s ve inspectÖzet - Kütüphane Kartı7Çok Biçimlilik ve Ördek Tiplemesi
Çok BiçimlilikÖrdek TiplemesiSoyut Metotlarcase ve SınıflarTekrar - Ödeme Yöntemleri2Erişimciler ve self
Okuyucular ve YazıcılarÖzel Setter'larMetotlarda selfKimlik ve EşitlikTekrar - Kişi Listesi5Kalıtım
Alt sınıflarMetotları geçersiz kılmasuper çağrısıis_a? ve üst sınıflarTekrar - Personel Maaşları8Özel Metotlar
Eşitlik ve hashOperatör Metotlarıİndeksleme ve EklemeÖzel KoleksiyonlarTekrar - Kesirler11Proje: Kütüphane Yönetimi
Kitaplar ve ÜyelerKitap Ödünç Alma3Sınıf Metotları ve Değişkenleri
Sınıf MetotlarıSınıf Örnek DeğişkenleriSabitlerFabrika MetotlarıTekrar - Kupon KodlarıKendi başına pratik yap: Online Ruby derleyicisi