is_a? והמחלקות הקדמוניות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Ruby של Coddy. שיעור 25 מתוך 57.
is_a?(Class) בודקת אם אובייקט הוא מופע של המחלקה הזאת או של אחת מתת־המחלקות שלה. kind_of? הוא שם נוסף לאותה מתודה:
class Animal
end
class Dog < Animal
end
rex = Dog.new
puts rex.is_a?(Dog)
puts rex.is_a?(Animal)
puts rex.is_a?(Object)
puts rex.kind_of?(String)פלט:
true
true
true
falseinstance_of? מחמירה יותר: היא true רק עבור המחלקה של האובייקט עצמו. obj.class מחזירה את המחלקה הזו:
class Animal
end
class Dog < Animal
end
rex = Dog.new
puts rex.instance_of?(Dog)
puts rex.instance_of?(Animal)
puts rex.classפלט:
true
false
Dogancestors מציג את המחלקות ש-Ruby מחפש בהן מתודות, החל במחלקה עצמה; הרשימה המלאה כוללת גם מודולים כמו Kernel, שנלמד בפרק 6, ולכן take(3) מציג את שלושת הפריטים הראשונים. אפשר להשוות בין מחלקות: Dog < Animal הוא true כאשר Dog יורשת מ-Animal:
class Animal
end
class Dog < Animal
end
p Dog.ancestors.take(3)
puts Dog < Animal
puts Animal < Dogפלט:
[Dog, Animal, Object]
true
falseהשתמשו ב־is_a? כשהקוד צריך להתייחס לקבוצת מחלקות באותו אופן, למשל כדי לספור את כל היונקים, בלי קשר לתת־המחלקה שלהם. חיפוש מחלקה מדויקת אחת באמצעות instance_of? נכשל ברגע שמישהו מוסיף תת־מחלקה:
mammals = animals.count { |a| a.is_a?(Mammal) } # כלבים, עטלפים, לווייתנים...
exact = animals.count { |a| a.instance_of?(Mammal) } # לא כולל אף תת־מחלקהאתגר
קלהגדירו את מחלקות בעלי החיים: Animal, Mammal < Animal, Bird < Animal, Dog < Mammal, Bat < Mammal ו־Penguin < Bird. Animal שומרת שם. לאחר מכן השלימו את פונקציית העזר describe(animal) בקובץ functions.rb: היא מחזירה Rex is a dog: mammal, Pingu is a penguin: bird, כאשר שם המחלקה באותיות קטנות והקבוצה נקבעת באמצעות is_a?.
הקוד שסופק קורא שורות dog Rex, יוצר את האובייקטים, מדפיס את describe עבור כל אחד מהם ולאחר מכן mammals: 2, birds: 1.
הקוד שלכם ייכתב בקבצים animal.rb, mammal.rb, bird.rb, dog.rb, bat.rb, penguin.rb ו־functions.rb. הקובץ main.rb מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
require_relative 'animal'
require_relative 'mammal'
require_relative 'bird'
require_relative 'dog'
require_relative 'bat'
require_relative 'penguin'
require_relative 'functions'
# קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
input = []
while (line = gets)
input << line.chomp
end
kinds = { "dog" => "Dog", "bat" => "Bat", "penguin" => "Penguin" }
animals = input.map do |line|
kind, name = line.split
Object.const_get(kinds[kind]).new(name)
end
animals.each { |a| puts describe(a) }
mammals = animals.count { |a| a.is_a?(Mammal) }
birds = animals.count { |a| a.is_a?(Bird) }
puts "mammals: #{mammals}, birds: #{birds}"
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
3מתודות ומשתנים של מחלקה
מתודות של מחלקהמשתני מופע של מחלקהקבועיםמתודות ליצירת מופעיםסיכום – קודי קופוןתרגלו בעצמכם: קומפיילר Ruby אונליין