تعدد الأشكال
جزء من قسم البرمجة كائنية التوجه في رحلة Swift على Coddy. الدرس 32 من 57.
تعدد الأشكال يعني أن جزءًا واحدًا من الشيفرة يعمل مع قيم من أنواع متعددة، وأن كل قيمة تستجيب بطريقتها الخاصة. تستدعي الحلقة أدناه sound() من دون معرفة الحيوان الذي تحتويه:
class Animal {
func sound() -> String { "..." }
}
class Dog: Animal {
override func sound() -> String { "Woof" }
}
class Cow: Animal {
override func sound() -> String { "Moo" }
}
let farm: [Animal] = [Dog(), Cow(), Dog()]
for a in farm { print(a.sound()) }الناتج:
Woof
Moo
Woofيحدّد Swift أي تنفيذ سيتم تشغيله في وقت التشغيل، انطلاقًا من الكائن الفعلي. لا يهم نوع المتغير المُعلَن؛ المهم هو نوع الكائن:
class Animal {
func sound() -> String { "..." }
}
class Cat: Animal {
override func sound() -> String { "Meow" }
}
let pet: Animal = Cat()
print(pet.sound())الناتج:
Meowتمنح البروتوكولات البُنى والتعدادات المرونة نفسها. تطبع هنا دالة واحدة أي قائمة من القيم Drawable:
protocol Drawable {
func draw() -> String
}
struct Line: Drawable {
let length: Int
func draw() -> String { String(repeating: "-", count: length) }
}
struct Box: Drawable {
func draw() -> String { "[ ]" }
}
func render(_ items: [any Drawable]) -> String {
items.map { $0.draw() }.joined(separator: " ")
}
print(render([Line(length: 3), Box(), Line(length: 1)]))الناتج:
--- [ ] -تستبدل التعددية الشكلية سلاسل if/switch الطويلة التي تتعامل مع أنواع الأشياء. فبدلًا من السؤال عن ماهية قيمة ما ثم تحديد الإجراء الذي ينبغي اتخاذه، تطلب من القيمة أن تنفّذ ذلك. وتعني إضافة نوع جديد إضافةَ نوع جديد، لا تعديل كل switch:
// بدون تعدد الأشكال
if kind == "dog" { print("Woof") } else if kind == "cow" { print("Moo") }
// مع تعدد الأشكال
for animal in farm { print(animal.sound()) }التحدي
سهليحتوي Animal على name وlegs() (4) وdescribe()، التي تُرجع Rex has 4 legs and says Woof، والمبنية من legs() وsound(). عرّف Dog (الصوت Woof) وBird (ساقان، والصوت Tweet) وSnake (0 من الساقين، والصوت Hiss) من خلال إعادة تعريف legs() وsound() فقط.
يقرأ الكود الم provided الأسطر dog,Rex أو bird,Pip أو snake,Kaa، ويخزّن الحيوانات في مصفوفة واحدة من نوع [Animal]، ويطبع describe() لكل منها.
ضع الكود الخاص بك في Animal.swift وDog.swift وBird.swift وSnake.swift. يحتوي main.swift على كود الإدخال/الإخراج الم provided، ولا يمكن تعديله.
جرّب بنفسك
// كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
var input: [String] = []
while let line = readLine() { input.append(line) }
var zoo: [Animal] = []
for line in input {
let p = line.split(separator: ",").map(String.init)
switch p[0] {
case "dog": zoo.append(Dog(name: p[1]))
case "bird": zoo.append(Bird(name: p[1]))
default: zoo.append(Snake(name: p[1]))
}
}
for a in zoo { print(a.describe()) }
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس البرمجة كائنية التوجه
1الأصناف والكائنات
العمل مع الملفاتتعريف الأصنافالأساليب وselfالمُهيِّئاتالأصناف هي مراجعمراجعة - بطاقة المكتبة4التغليف
التحكم في الوصولللقراءة فقط من الخارجحماية الحالةالمهيئات القابلة للفشلمراجعة - الحساب البنكي7تعدد الأشكال والأنواع العامة
تعدد الأشكالتحويل الأنواعالدوال العامةالأنواع العامةمراجعة - حاسبة الأشكالتدرّب بنفسك: Playground لـ Swift