Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

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 عبر الإنترنت