Menu
Coddy logo textTech

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
false

instance_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
Dog

ancestors מציג את המחלקות ש-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) }  # לא כולל אף תת־מחלקה
challenge icon

אתגר

קל

הגדירו את מחלקות בעלי החיים: 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}"
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Ruby אונליין