Ö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; yalnızca nesnenin bu yönteme sahip olması gerekir. "Ördek gibi yürüyorsa ve ördek gibi vaklıyorsa, ördektir." Buna ördek tiplemesi denir: ortak bir üst sınıfı olmayan sınıflar bile 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 işin içindedir. Yalnızca << kullanan bir yöntem, bir diziyle, bir dizeyle 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 herkese açık bir yönteme sahip olup olmadığını sorar. Bir nesnenin isteğe bağlı bir özelliği destekleyip desteklemeyebileceği durumlarda 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 printNesne bu metoda sahip olmadığında, çağrı NoMethodError hatasını yükseltir; bu hatanın mesajı yöntemin ve nesnenin adını belirtir. Ördek tiplemesi, kendisine gönderilen yöntemleri yanıtlayabilen her nesnenin geçirilmesine 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
KolayPrinter ve LineCounter sınıflarını ve functions.rb içindeki export(items, target) yardımcı işlevini tamamla. export, her öğeyi target << item.to_s ile hedefe gönderir ve hedefi döndürür. Printer#<<, metni satır numarasıyla, 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, bunları bir diziye (p ile yazdırılır), yeni bir dizeye (p ile yazdırılır), bir Printer'a ve bir LineCounter'a (puts ile yazdırılır) aktarır.
Kodun printer.rb, line_counter.rb ve functions.rb dosyalarına yazılmalıdı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