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

الفئات الفرعية

جزء من قسم البرمجة كائنية التوجه في رحلة Swift على Coddy. الدرس 22 من 57.

تتيح الوراثة لفئة أن تبني على فئة أخرى. تجعل class Dog: Animal من Dog فئة فرعية من الفئة الفائقة Animal: يمتلك الكلب كل خاصية وكل طريقة للحيوان، بالإضافة إلى ما تضيفه Dog:

class Animal {
    var name: String
    init(name: String) { self.name = name }
    func describe() -> String { "\(name) is an animal" }
}

class Dog: Animal {
    func fetch() -> String { "\(name) fetches the ball" }
}

let rex = Dog(name: "Rex")
print(rex.describe())
print(rex.fetch())

الناتج:

Rex is an animal
Rex fetches the ball

ترث الفئة الفرعية التي لا تضيف أي خصائص مخزّنة مُهيئات الفئة الفائقة، ولهذا تعمل Dog(name:) من دون وجود init في Dog. تمثّل الوراثة علاقة is-a: كل كلب هو حيوان، لذا يمكن استخدام Dog أينما كان متوقعًا استخدام Animal:

class Animal {
    var name: String
    init(name: String) { self.name = name }
}

class Cat: Animal {}
class Dog: Animal {}

let pets: [Animal] = [Cat(name: "Tom"), Dog(name: "Rex")]
for pet in pets { print(pet.name) }

الناتج:

Tom
Rex

الفئات فقط تدعم الوراثة؛ ولا يمكن للهياكل والتعدادات أن ترث. للفئة فئة فائقة واحدة كحد أقصى، لكن يمكن للفئة الفائقة أن تمتلك العديد من الفئات الفرعية، مما يشكّل تسلسلاً هرميًا:

class Vehicle { var wheels = 0 }
class Car: Vehicle { }        // Car هو Vehicle
class Bike: Vehicle { }       // Bike هو Vehicle
// struct Truck: Vehicle { }  // error: لا يمكن للـ structs أن ترث

ضع ما تشترك فيه جميع الفئات الفرعية في الفئة الفائقة، وضع الاختلافات فقط في كل فئة فرعية. عندما لا يكون أحد النوعين نوعًا من الآخر فعليًا، تكون الوراثة أداة غير مناسبة؛ وغالبًا ما تكون الخاصية التي تحتوي على النوع الآخر أنسب.

class Shape {
    var name: String
    init(name: String) { self.name = name }
    func label() -> String { "a \(name)" }
}

class Square: Shape {
    var side = 1.0
    func area() -> Double { side * side }
}

let s = Square(name: "square")
s.side = 3
print(s.label())
print(s.area())

المخرجات:

a square
9.0
challenge icon

التحدي

سهل

تخزّن Employee قيمة name وقيمة salary، وتحتوي على أسلوب raise(by:) يزيد الراتب بنسبة مئوية (مع التقريب إلى الأسفل). صرّح عن فئة فرعية باسم Manager تضيف خاصية مخزّنة باسم reports (مصفوفة من الأسماء، فارغة في البداية) وأسلوبًا باسم addReport(_:)، بالإضافة إلى أسلوب teamSize() الذي يعيد عدد التقارير.

ينشئ الكود المُقدَّم مديرًا من السطر الأول (name,salary)، ويضيف كل اسم لاحق كتقرير، ويمنحه زيادة بنسبة 10%، ثم يطبع Ada earns 5500 and leads 2.

ضع كودك في Employee.swift وManager.swift. يحتوي main.swift على كود الإدخال/الإخراج المُقدَّم ولا يمكن تعديله.

جرّب بنفسك

// كود الإدخال/الإخراج المُزوَّد: أبقِه كما هو
var input: [String] = []
while let line = readLine() { input.append(line) }
let head = input[0].split(separator: ",").map(String.init)
let boss = Manager(name: head[0], salary: Int(head[1])!)
for name in input.dropFirst() { boss.addReport(name) }
boss.raise(by: 10)
print("\(boss.name) earns \(boss.salary) and leads \(boss.teamSize())")
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس البرمجة كائنية التوجه

تدرّب بنفسك: Playground لـ Swift