מחלקות פתוחות ותת-מחלקות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Kotlin של Coddy. שיעור 17 מתוך 57.
ירושה מאפשרת למחלקה אחת להתבסס על מחלקה אחרת. מחלקת המשנה מקבלת את כל המאפיינים והמתודות של מחלקת-העל שלה ויכולה להוסיף משלה. מחלקות Kotlin סגורות כברירת מחדל, לכן יש לסמן מחלקה ב-open לפני שמחלקה אחרת יכולה לרשת ממנה:
open class Animal(val name: String) {
fun describe() = "$name is an animal"
}
class Dog(name: String) : Animal(name) {
fun fetch() = "$name fetches the ball"
}בתוך main:
val rex = Dog("Rex")
println(rex.describe())
println(rex.fetch())פלט:
Rex is an animal
Rex fetches the ballclass Dog(name: String) : Animal(name) מציין ש־Dog יורשת מ־Animal ומעבירה את name לבנאי של מחלקת־העל. לפרמטר אין val, כי המאפיין כבר קיים ב־Animal. אי אפשר לרשת ממחלקה שאינה open:
class Plant(val name: String)
// class Tree(name: String) : Plant(name) // שגיאה: הטיפוס הזה הוא final, ולכן אי אפשר לרשת ממנו
open class Vehicle(val wheels: Int)
class Bike : Vehicle(2) // מעביר ערך קבוע
class Truck(val load: Int) : Vehicle(6) // מוסיף מאפיין משלוDog הוא Animal, ולכן אפשר להשתמש במופע של תת-מחלקה בכל מקום שבו מצופה טיפוס של מחלקת-העל. List<Animal> אחד יכול להכיל כלבים, חתולים ובעלי חיים רגילים, ולכל איבר יש את החברים של Animal:
open class Animal(val name: String) {
fun describe() = "$name is an animal"
}
class Dog(name: String) : Animal(name)
class Cat(name: String, val indoor: Boolean) : Animal(name)בתוך main:
val pets: List<Animal> = listOf(Dog("Rex"), Cat("Tom", true), Animal("Generic"))
for (p in pets) println(p.describe())פלט:
Rex is an animal
Tom is an animal
Generic is an animalירושה ממדלת יחס של is-a: כלב הוא בעל חיים, חשבון חיסכון הוא חשבון. כשמחלקה אחת רק משתמשת במחלקה אחרת (למכונית יש מנוע), תן לה מאפיין מהסוג הזה במקום זאת. מחלקות סגורות הן ברירת המחדל ב-Kotlin, ולכן מחלקה שמיועדת להרחבה מצהירה על כך באמצעות open, וכל מחלקה אחרת שומרת על התנהגותה מוגנת מפני מחלקות משנה.
open class Account(val owner: String)
class SavingsAccount(owner: String) : Account(owner) // הוא סוג של: הורשה
class Engine(val horsepower: Int)
class Car(val engine: Engine) // יש לו: מאפייןאתגר
קלManager חוזרת על מה שכבר יש ב-Employee. הפוך את Employee למחלקה פתוחה ואת Manager לתת-המחלקה שלה: Manager(name: String, salary: Int) מעבירה את שני הערכים אל Employee ומשאירה רק את מה שחדש, רשימה פרטית של שמות העובדים שעליהם היא מדווחת, עם addReport(name) ו-teamSize(). ב-Employee, raise(percent) מגדילה את המשכורת באחוז הנתון, בעיגול כלפי מטה, ו-describe() מחזירה את Ada earns 5500.
הקוד שסופק יוצר מנהל מהשורה הראשונה (name,salary), מוסיף כל שם שמופיע אחריה כעובד המדווח אליו, מעניק העלאה של 10% ומדפיס את Ada earns 5500 and leads 2, ואז בודק שמנהל הוא Employee.
הקוד שלך צריך להופיע ב-Employee.kt וב-Manager.kt. הקובץ Main.kt מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
fun main() {
// קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
val input = generateSequence(::readLine).toList()
val (name, salary) = input[0].split(",")
val boss = Manager(name, salary.toInt())
for (report in input.drop(1)) boss.addReport(report)
boss.raise(10)
println("${boss.describe()} and leads ${boss.teamSize()}")
println("a manager is an employee: ${(boss as Any) is Employee}")
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1מחלקות ואובייקטים
עבודה עם קבציםהגדרת מחלקותבנאים ראשייםבלוקי init ואימות נתוניםבנאים משנייםסיכום – כרטיס ספרייהתרגלו בעצמכם: Kotlin אונליין