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 אונליין