מעבדת קוד זו היא חלק מקורס האתחול של מתכנתים בקוטלין. כדי להפיק את המקסימום מהקורס הזה, יש לפעול ברצף לפי קודי שיעור ה-Lab. בהתאם לידע שלכם, ייתכן שתוכלו לדלג על קטעים מסוימים. הקורס הזה מיועד למתכנתים בעלי שפה ממוקדת אובייקטים שרוצים ללמוד Kotlin.
מבוא
ב-Codelab הזה אתם יוצרים תוכנית Kotlin ולומדים על קורסים ואובייקטים ב-Kotlin. רוב התוכן הזה יהיה מוכר לכם אם אתם מכירים שפה אחרת המבוססת על אובייקטים, אבל ל-Kotlin יש כמה הבדלים חשובים כדי להפחית את כמות הקוד שאתם צריכים לכתוב. יש לך גם מידע על כיתות מופשטות ועל האצלת ממשק.
במקום לפתח אפליקציה לדוגמה אחת, השיעורים בקורס הזה נועדו לפתח את הידע שלכם, אך אינם תלויים זה בזה כדי שתוכלו לעיין בסעיפים שאתם מכירים. כדי לקשר ביניהם, רבות מהדוגמאות משתמשות בעיצוב של אקווריום. אם אתם רוצים לראות את הסיפור המלא באקווריום, כדאי לנסות את הקורס של מתכנתים בקוטג'ין באוניברסיטה.
דברים שחשוב לדעת
- היסודות של קוטלין, כולל סוגים, אופרטורים ולופ
- תחביר הפונקציה Kotlin'
- העקרונות הבסיסיים של תכנות הממוקד באובייקטים
- היסודות של IDE, כמו IntelliJ IDEA או Android Studio
מה תלמדו
- איך ליצור כיתות ולגשת לנכסים בקוטלין
- איך ליצור ולבנות כיתה בקוטלין ולהשתמש בהם
- איך יוצרים סיווג משנה ואיך פועלת הירושה
- מידע על מחלקות, ממשקים והקצאת ממשק מופשטים
- איך יוצרים מחלקות נתונים ואיך משתמשים בהן
- איך להשתמש בטון יחיד, באנום ובכיתות אטומות
הפעולות שתבצעו:
- יצירת כיתה עם מאפיינים
- יצירת בנאי לכיתה
- יצירת סיווג משנה
- בחינת דוגמאות של כיתות וממשקים מופשטים
- יצירת סיווג נתונים פשוט
- מידע על טון יחיד, אנטום וכיתות אטומות
מונחי התכנות הבאים כבר אמורים להיות מוכרים לכם:
- כיתות הן רישומים של אובייקטים. לדוגמה, כיתה
Aquarium
היא הציור של יצירת אובייקט באקווריום. - אובייקטים הם מופעים של כיתות; אובייקט באקווריום הוא
Aquarium
אחד בפועל. - מאפיינים הם מאפיינים של כיתות, כמו האורך, הרוחב והגובה של
Aquarium
. - שיטות, שנקראות גם פונקציות לחברים, הן הפונקציונליות של הכיתה. שיטות הן מה שניתן "לסמן במירכאות". לדוגמה, אפשר
fillWithWater()
של אובייקטAquarium
. - ממשק הוא מפרט שכיתות יכולות להטמיע. לדוגמה, ניקוי נפוץ לאובייקטים שאינם אקווריומים, וניקיון בדרך כלל דומה לאובייקטים שונים. לכן יכול להיות לך ממשק בשם
Clean
שמגדיר שיטתclean()
. הכיתהAquarium
יכולה להטמיע את הממשקClean
כדי לנקות את האקווריום עם ספוג רך. - חבילות הן דרך לקבץ קוד קשור כדי לשמור על סדר או ליצור ספריית קוד. לאחר יצירת חבילה, אפשר לייבא את תוכן החבילה לקובץ אחר ולעשות בה שימוש חוזר בקוד ובכיתות.
במשימה הזו יוצרים חבילה חדשה ומחלקה עם מאפיינים ושיטה מסוימים.
שלב 1: יצירת חבילה
חבילות יכולות לעזור לכם לשמור על סדר בקוד.
- בחלונית Project (פרויקט), מתחת לפרויקט שלום Kotlin, לוחצים לחיצה ימנית על התיקייה src.
- בוחרים באפשרות New > Package (חבילה & חדשה) וקוראים לה
example.myapp
.
שלב 2: יצירת כיתה עם מאפיינים
כיתות מוגדרות במילת המפתח class
, ושמות הכיתות מתחילים באות רישית.
- לוחצים לחיצה ימנית על החבילה example.myapp.
- בוחרים באפשרות > חדש; קובץ Kotlin / כיתה.
- בקטע מיון, בוחרים כיתה ו נותנים שם לכיתה
Aquarium
. IntelliJ IDEA כולל את שם החבילה בקובץ ויוצר בשבילכם כיתה אחת (Aquarium
) ריקה. - בתוך הכיתה
Aquarium
, מגדירים ומתחיליםvar
מאפיינים של רוחב, גובה ואורך (בס"מ). מפעילים את הנכסים עם ערכי ברירת המחדל.
package example.myapp
class Aquarium {
var width: Int = 20
var height: Int = 40
var length: Int = 100
}
מאחורי הקלעים, Kotlin יוצר באופן אוטומטי getter ומגדיר את הנכסים כפי שהם מוגדרים במחלקה Aquarium
, כך שאתם יכולים לגשת אליהם ישירות, לדוגמה, myAquarium.length
.
שלב 3: יוצרים פונקציה מסוג()
יצירת קובץ חדש בשם main.kt
כדי לשמור את הפונקציה main()
.
- בחלונית Project (פרויקט) מימין, לוחצים לחיצה ימנית על החבילה example.myapp.
- בוחרים באפשרות > חדש; קובץ Kotlin / כיתה.
- בתפריט הנפתח Kind, משאירים את הבחירה כקובץ, ונותנים לקובץ את השם
main.kt
. IntelliJ IDEA כולל את שם החבילה, אבל לא כולל הגדרות של כיתה עבור הקובץ. - מגדירים פונקציה ב-
buildAquarium()
ויוצרים בתוכה מופע שלAquarium
. כדי ליצור מכונה, יש להפנות את הכיתה פונקציה מסוימת,Aquarium()
. פעולה זו בונה את הרכיב של הכיתה ויוצרת מופע של הכיתהAquarium
, בדומה לשימוש ב-new
בשפות אחרות. - צריך להגדיר פונקציה ב-
main()
ולהתקשר ל-buildAquarium()
.
package example.myapp
fun buildAquarium() {
val myAquarium = Aquarium()
}
fun main() {
buildAquarium()
}
שלב 4: הוספת שיטה
- בכיתה
Aquarium
, מוסיפים שיטה להדפסה של מאפייני האקווריום.
fun printSize() {
println("Width: $width cm " +
"Length: $length cm " +
"Height: $height cm ")
}
- ב
main.kt
, בbuildAquarium()
, יש להתקשר אלprintSize()
בשיטהmyAquarium
.
fun buildAquarium() {
val myAquarium = Aquarium()
myAquarium.printSize()
}
- הפעל את התוכנית על ידי לחיצה על המשולש הירוק לצד הפונקציה
main()
. בודקים את התוצאה.
⇒ Width: 20 cm Length: 100 cm Height: 40 cm
- ב-
buildAquarium()
, מוסיפים קוד כדי להגדיר את הגובה ל-60 ולהדפיס את מאפייני המאפיין ששונו.
fun buildAquarium() {
val myAquarium = Aquarium()
myAquarium.printSize()
myAquarium.height = 60
myAquarium.printSize()
}
- מפעילים את התוכנית וצופים בפלט.
⇒ Width: 20 cm Length: 100 cm Height: 40 cm Width: 20 cm Length: 100 cm Height: 60 cm
במשימה הזו בונים בנאי עבור הכיתה וממשיכים לעבוד עם הנכסים.
שלב 1: יצירת מבנה
בשלב זה מוסיפים בנאי למחלקה Aquarium
שיצרתם במשימה הראשונה. בדוגמה הקודמת, כל מופע של Aquarium
נוצר עם אותם המימדים. ניתן לשנות את המאפיינים לאחר יצירת המאפיינים, אך פשוט יותר ליצור את הגודל הנכון בתור התחלה.
בשפות תכנות מסוימות, המבנה מוגדר על ידי יצירת שיטה בכיתה עם שם זהה לכיתה. ב-Kotlin, מגדירים את ה-constructor ישירות בהצהרת הכיתה עצמה, תוך ציון הפרמטרים בתוך הסוגריים, כאילו הייתה שיטה. כמו בפונקציות ב-Kotlin, הפרמטרים האלה יכולים לכלול ערכי ברירת מחדל.
- בכיתה
Aquarium
, משנים את ההגדרה של הכיתה כך שתכלול שלושה פרמטרים של מאפיינים שיוצרים ערכי ברירת מחדל ב-length
, ב-width
וב-height
, ומקצים אותם למאפיינים המתאימים.
class Aquarium(length: Int = 100, width: Int = 20, height: Int = 40) {
// Dimensions in cm
var length: Int = length
var width: Int = width
var height: Int = height
...
}
- השיטה הקומפקטית יותר של Kotlin היא להגדיר את המאפיינים ישירות באמצעות ה-constructor באמצעות
var
אוval
, ו-Cotlin גם יוצרת באופן אוטומטי את אובייקטי ה-Get וסוג הסלקטורים. לאחר מכן תוכלו להסיר את הגדרות הנכס בגוף הכיתה.
class Aquarium(var length: Int = 100, var width: Int = 20, var height: Int = 40) {
...
}
- כשיוצרים אובייקט
Aquarium
עם הרכיב הזה, אפשר לציין ארגומנטים ולא לקבל את ערכי ברירת המחדל, או לציין רק חלק מהם, או לציין את כולם וליצורAquarium
בהתאמה אישית. בפונקציהbuildAquarium()
יש לנסות דרכים שונות ליצירת אובייקטAquarium
באמצעות פרמטרים בעלי שם.
fun buildAquarium() {
val aquarium1 = Aquarium()
aquarium1.printSize()
// default height and length
val aquarium2 = Aquarium(width = 25)
aquarium2.printSize()
// default width
val aquarium3 = Aquarium(height = 35, length = 110)
aquarium3.printSize()
// everything custom
val aquarium4 = Aquarium(width = 25, height = 35, length = 110)
aquarium4.printSize()
}
- מפעילים את התוכנית ובודקים את הפלט.
⇒ Width: 20 cm Length: 100 cm Height: 40 cm Width: 25 cm Length: 100 cm Height: 40 cm Width: 20 cm Length: 110 cm Height: 35 cm Width: 25 cm Length: 110 cm Height: 35 cm
שימו לב: לא היה צורך להעמיס את המבנה ולכתוב גרסה שונה לכל אחד מהמקרים האלו (וכן להוסיף עוד כמה שילובים). קוטלין יוצרת את מה שדרוש מערכי ברירת המחדל ומהפרמטרים שצוינו.
שלב 2: הוספה של בלוקי init
המבנים שצוינו למעלה רק מצהירים על נכסים ומקצים להם את הערך של הביטוי. אם הבנייה שלך צריכה קוד אתחול נוסף, אפשר למקם אותו בבלוק init
אחד או יותר. בשלב זה, מוסיפים כמה בלוקים של init
למחלקה Aquarium
.
- בכיתה
Aquarium
, מוסיפים בלוק שלinit
כדי להדפיס שהאובייקט מופעל, ובלוק שני כדי להדפיס את עוצמת הקול בליטר.
class Aquarium (var length: Int = 100, var width: Int = 20, var height: Int = 40) {
init {
println("aquarium initializing")
}
init {
// 1 liter = 1000 cm^3
println("Volume: ${width * length * height / 1000} l")
}
}
- מפעילים את התוכנית ובודקים את הפלט.
aquarium initializing
Volume: 80 l
Width: 20 cm Length: 100 cm Height: 40 cm
aquarium initializing
Volume: 100 l
Width: 25 cm Length: 100 cm Height: 40 cm
aquarium initializing
Volume: 77 l
Width: 20 cm Length: 110 cm Height: 35 cm
aquarium initializing
Volume: 96 l
Width: 25 cm Length: 110 cm Height: 35 cm
שימו לב שהבלוקים של init
מתבצעים לפי הסדר שבו הם מופיעים בהגדרה של הכיתה. כל הבלוקים מתבצעים כשמפעילים את ה-constructor.
שלב 3: מידע על בנאים משניים
בשלב הזה תלמדו על בנאים משניים והוסיפו מישהו לכיתה. בנוסף לבנאי ראשי, שיכול להיות לו בלוק אחד של init
או יותר, מחלקה של Kotlin יכולה לכלול גם בנאי משני אחד או יותר כדי לאפשר עומס יתר של בנאים, כלומר קבלנים עם ארגומנטים שונים.
- בכיתה
Aquarium
, יש להוסיף בנאי משני שיש בו מספר דגים כארגומנט בעזרת מילת המפתחconstructor
. יוצרים מאפיין 'מכל' שלval
עבור הנפח המחושב של האקווריום בליטרים לפי מספר הדגים. מניחים 2 ליטרים של מים לדגים, וגם מעט שטח נוסף כדי שהמים לא נשפכו.
constructor(numberOfFish: Int) : this() {
// 2,000 cm^3 per fish + extra room so water doesn't spill
val tank = numberOfFish * 2000 * 1.1
}
- בתוך המרכיב המשני, יש לשמור על האורך והרוחב (שהוגדרו בבונה הראשי) זהים, ולחשב את הגובה הדרוש כדי להפוך את המאגר לנפח הנתון.
// calculate the height needed
height = (tank / (length * width)).toInt()
- בפונקציה
buildAquarium()
, צריך להוסיף שיחה כדי ליצורAquarium
באמצעות המבנה המשני החדש. מדפיסים את הגודל והנפח.
fun buildAquarium() {
val aquarium6 = Aquarium(numberOfFish = 29)
aquarium6.printSize()
println("Volume: ${aquarium6.width * aquarium6.length * aquarium6.height / 1000} l")
}
- מפעילים את התוכנית וצופים בפלט.
⇒ aquarium initializing Volume: 80 l Width: 20 cm Length: 100 cm Height: 31 cm Volume: 62 l
שים לב שהכרך מודפס פעמיים, פעם אחת באמצעות הבלוק init
ב-constructor הראשי לפני ביצוע ה-constructor המשני, ופעם אחת באמצעות הקוד ב-buildAquarium()
.
אפשר לכלול את מילת המפתח constructor
גם בבנאי הראשי, אבל ברוב המקרים היא לא נחוצה.
שלב 4: הוספת getter של נכס חדש
בשלב הזה מוסיפים רכיב getter של מאפיין בוטה. Kotlin מגדיר באופן אוטומטי גוטרים ומגדירים כאשר מגדירים נכסים, אך לפעמים יש להתאים או לחשב את ערך הנכס. לדוגמה, הדפסת את הנפח של ה-Aquarium
. כדי להגדיר את הנפח כנכס, אפשר להגדיר משתנה ולקבל אותו. מאחר שיש לחשב את volume
, המקבל צריך להחזיר את הערך המחושב. אפשר לעשות זאת באמצעות פונקציה שיש בה שורה אחת.
- בכיתה
Aquarium
, מגדירים נכסInt
בשםvolume
, ומגדירים שיטתget()
לחישוב המחשב בשורה הבאה.
val volume: Int
get() = width * height * length / 1000 // 1000 cm^3 = 1 l
- מסירים את הבלוק של
init
שמודפס על הנפח. - יש להסיר את הקוד ב-
buildAquarium()
שמודפס את הכרך. - בשיטה
printSize()
, מוסיפים קו כדי להדפיס את הכרך.
fun printSize() {
println("Width: $width cm " +
"Length: $length cm " +
"Height: $height cm "
)
// 1 l = 1000 cm^3
println("Volume: $volume l")
}
- מפעילים את התוכנית וצופים בפלט.
⇒ aquarium initializing Width: 20 cm Length: 100 cm Height: 31 cm Volume: 62 l
המימדים ועוצמת הקול זהים לאלה שלפני כן, אך עוצמת הקול מודפסת פעם אחת בלבד לאחר שהאובייקט מופעל במלואו על ידי ה-constructor הראשי וה-constructor המשני.
שלב 5: הוספה של מגדיר נכסים
בשלב זה יוצרים נכס חדש שלפיו הוגדר הנפח.
- בכיתה
Aquarium
, צריך לשנות אתvolume
ל-var
כדי שניתן יהיה להגדיר אותו יותר מפעם אחת. - יש להוסיף מגדיר עבור הנכס
volume
על ידי הוספת שיטתset()
מתחת למקלט. פעולה זו תחשב מחדש את הגובה על בסיס כמות המים שסופקה. לפי השיטה המקובלת, שם הפרמטר המוגדר הואvalue
, אבל אפשר לשנות אותו.
var volume: Int
get() = width * height * length / 1000
set(value) {
height = (value * 1000) / (width * length)
}
- ב-
buildAquarium()
יש להוסיף קוד כדי להגדיר את נפח האקווריום ל-70 ליטרים. מדפיסים את הגודל החדש.
fun buildAquarium() {
val aquarium6 = Aquarium(numberOfFish = 29)
aquarium6.printSize()
aquarium6.volume = 70
aquarium6.printSize()
}
- הפעילו שוב את התוכנית ובדקו את הגובה והנפח שהשתנו.
⇒ aquarium initialized
Width: 20 cm Length: 100 cm Height: 31 cm
Volume: 62 l
Width: 20 cm Length: 100 cm Height: 35 cm
Volume: 70 l
עד כה לא היו שינויים בחשיפה, כמו public
או private
. הסיבה לכך היא שכברירת מחדל, כל מה ששמו של קוטלין גלוי לכולם. כלומר, ניתן לגשת לכל מה שנמצא בכל מקום, כולל לכיתות, לשיטות, לנכסים ולמשתנים של חברי הקבוצה.
בקוטלין, מחלקות, אובייקטים, ממשקים, מבנים, פונקציות, מאפיינים ורכיבי ההגדרה שלהם יכולים להיות מגבילי חשיפה:
- המשמעות של
public
היא 'גלוי מחוץ לכיתה'. הכול גלוי לכול כברירת מחדל, כולל משתנים ושיטות של הכיתה. - המשמעות של
internal
היא שהיא תהיה גלויה רק במודול הזה. מודול הוא קבוצה של קובצי Kotlin שמורכבים יחד, לדוגמה ספרייה או אפליקציה. private
פירושו שהוא יוצג רק בכיתה הזו (או בקובץ המקור אם אתם עובדים עם פונקציות).- הקובץ
protected
זהה ל-private
, אבל הוא יהיה גלוי גם לכל כיתות המשנה.
מידע נוסף זמין בקטע חשיפה לגבי שינויים בתיעוד של Kotlin.
משתנים של חברים
המאפיינים בכיתה או במשתנים של חברי הקבוצה הם public
כברירת מחדל. אם מגדירים אותם באמצעות var
, אפשר לשנות אותם, כלומר ניתן לקרוא ולכתוב אותם. אם מגדירים את הערכים שלהם כ-val
, הם מוגדרים לקריאה בלבד לאחר האתחול.
אם רוצים להגדיר קוד שהמערכת תוכל לקרוא או לכתוב אבל לא ניתן לקרוא אותו רק באמצעות קוד חיצוני, אפשר להשאיר את הנכס ואת הנכס שלו כגלוי לכול ולהצהיר על הפרטיות שלו כמפורט למטה, כפי שמוצג בהמשך.
var volume: Int
get() = width * height * length / 1000
private set(value) {
height = (value * 1000) / (width * length)
}
במשימה הזו לומדים איך כיתות משנה וירושה פועלות בקוטלין. הם דומים למה שראיתם בשפות אחרות, אבל יש כמה הבדלים.
כברירת מחדל, לא ניתן לסווג כיתות ב-Kotlin כברירת מחדל. באופן דומה, רמות משנה לא יכולות לעקוף את המאפיינים ואת המשתנים של החברים בקבוצה (אם כי ניתן לגשת אליהם).
יש לסמן את הכיתה כ-open
כדי לאפשר סיווג שלה. באופן דומה, יש לסמן נכסים ומשתני חברות בתור open
כדי לשנות אותם בתת-המחלקה. נדרשת מילת המפתח open
כדי למנוע דליפה בטעות של פרטי הטמעה כחלק מהממשק של הכיתה.
שלב 1: פתיחת הכיתה בנושא האקווריום
בשלב זה, תיצרו את Aquarium
כיתה open
, כדי שתוכלו לעקוף אותה בשלב הבא.
- ניתן לסמן את המחלקה
Aquarium
ואת כל המאפיינים שלה באמצעות מילת המפתחopen
.
open class Aquarium (open var length: Int = 100, open var width: Int = 20, open var height: Int = 40) {
open var volume: Int
get() = width * height * length / 1000
set(value) {
height = (value * 1000) / (width * length)
}
- יש להוסיף נכס
shape
פתוח עם הערך"rectangle"
.
open val shape = "rectangle"
- הוספה של נכס
water
פתוח עם getter שמחזירה 90% מהנפח שלAquarium
.
open var water: Double = 0.0
get() = volume * 0.9
- יש להוסיף קוד בשיטה
printSize()
כדי להדפיס את הצורה, ואת כמות המים כאחוז מהנפח.
fun printSize() {
println(shape)
println("Width: $width cm " +
"Length: $length cm " +
"Height: $height cm ")
// 1 l = 1000 cm^3
println("Volume: $volume l Water: $water l (${water/volume*100.0}% full)")
}
- ב-
buildAquarium()
, משנים את הקוד כדי ליצורAquarium
ב-width = 25
, ב-length = 25
וב-height = 40
.
fun buildAquarium() {
val aquarium6 = Aquarium(length = 25, width = 25, height = 40)
aquarium6.printSize()
}
- מפעילים את התוכנית וצופים בפלט החדש.
⇒ aquarium initializing rectangle Width: 25 cm Length: 25 cm Height: 40 cm Volume: 25 l Water: 22.5 l (90.0% full)
שלב 2: יצירה של סיווג משנה
- יש ליצור תת-קבוצה של
Aquarium
הנקראתTowerTank
, שבה מוטמע מיכל גליל במקום מנהרה מלבנית. אפשר להוסיף אתTowerTank
מתחת ל-Aquarium
, כי אפשר להוסיף כיתה נוספת באותו קובץ כמו המחלקהAquarium
. - ב-
TowerTank
, יש לשנות את מאפייןheight
, שמוגדר ב-constructor. כדי לעקוף נכס, צריך להשתמש במילת המפתחoverride
בסיווג המשנה.
- יש לבנות את
TowerTank
עבורdiameter
. יש להשתמש ב-diameter
ל-length
ול-width
כשמתקשרים ל-constructor במחלקה-העל שלAquarium
.
class TowerTank (override var height: Int, var diameter: Int): Aquarium(height = height, width = diameter, length = diameter) {
- אפשר לעקוף את מאפיין הנפח כדי לחשב גליל. הנוסחה עבור גליל היא פאי כפול הרדיוס בכפולות הגובה. צריך לייבא את הערך הקבוע
PI
שלjava.lang.Math
.
override var volume: Int
// ellipse area = π * r1 * r2
get() = (width/2 * length/2 * height / 1000 * PI).toInt()
set(value) {
height = ((value * 1000 / PI) / (width/2 * length/2)).toInt()
}
- ב-
TowerTank
, משנים את מאפייןwater
ל-80% מהעוצמת הקול.
override var water = volume * 0.8
- יש לשנות את
shape
ל-"cylinder"
.
override val shape = "cylinder"
- הכיתה האחרונה שלך ב-
TowerTank
אמורה להיראות בערך כך:
Aquarium.kt
:
package example.myapp
import java.lang.Math.PI
... // existing Aquarium class
class TowerTank (override var height: Int, var diameter: Int): Aquarium(height = height, width = diameter, length = diameter) {
override var volume: Int
// ellipse area = π * r1 * r2
get() = (width/2 * length/2 * height / 1000 * PI).toInt()
set(value) {
height = ((value * 1000 / PI) / (width/2 * length/2)).toInt()
}
override var water = volume * 0.8
override val shape = "cylinder"
}
- ב
buildAquarium()
, יוצריםTowerTank
בקוטר 25 ס"מ וגובה של 45 ס"מ. מדפיסים את המידה.
main.kt:
package example.myapp
fun buildAquarium() {
val myAquarium = Aquarium(width = 25, length = 25, height = 40)
myAquarium.printSize()
val myTower = TowerTank(diameter = 25, height = 40)
myTower.printSize()
}
- מפעילים את התוכנית וצופים בפלט.
⇒ aquarium initializing rectangle Width: 25 cm Length: 25 cm Height: 40 cm Volume: 25 l Water: 22.5 l (90.0% full) aquarium initializing cylinder Width: 25 cm Length: 25 cm Height: 40 cm Volume: 18 l Water: 14.4 l (80.0% full)
לפעמים אתם רוצים להגדיר התנהגות או מאפיינים משותפים שישותפו בין הכיתות הקשורות. קוטלין מציע שתי דרכים לעשות זאת, ממשקים וכיתות מופשטות. במשימה הזו, יוצרים מחלקת AquariumFish
מופשטת לנכסים משותפים לכל הדגים. אתה יוצר ממשק בשם FishAction
כדי להגדיר התנהגות המשותפת לכל הדגים.
- לא ניתן ליצור כיתה מופשטת וממשק לבד, כך שלא ניתן ליצור אובייקטים מסוג זה ישירות.
- בכיתות המופשטות יש בנאים.
- לממשקים לא יכול להיות לוגיקה של בונה או אחסון של מצבים כלשהם.
שלב 1. יצירת כיתה מופשטת
- בקטע example.myapp, יוצרים קובץ חדש,
AquariumFish.kt
. - יש ליצור כיתה שנקראת גם
AquariumFish
ולסמן אותה עםabstract
. - יש להוסיף נכס
String
אחד,color
, ולסמן אותו באמצעותabstract
.
package example.myapp
abstract class AquariumFish {
abstract val color: String
}
- אפשר ליצור שתי קטגוריות משנה של
AquariumFish
,Shark
וPlecostomus
. - מכיוון ש-
color
מופשט, מחלקות המשנה חייבות להטמיע אותו. הגדרתShark
אפור ו-Plecostomus
זהב.
class Shark: AquariumFish() {
override val color = "gray"
}
class Plecostomus: AquariumFish() {
override val color = "gold"
}
- ב-main.kt, יוצרים פונקציה
makeFish()
כדי לבדוק את הכיתות. ליצור אובייקטShark
וPlecostomus
באופן מיידי, ולאחר מכן להדפיס את הצבע של כל אחד מהם. - יש למחוק את קוד הבדיקה הקודם ב-
main()
ולהוסיף שיחה אלmakeFish()
. הקוד צריך להיראות בערך כמו הקוד הבא.
main.kt
:
package example.myapp
fun makeFish() {
val shark = Shark()
val pleco = Plecostomus()
println("Shark: ${shark.color}")
println("Plecostomus: ${pleco.color}")
}
fun main () {
makeFish()
}
- מפעילים את התוכנית וצופים בפלט.
⇒ Shark: gray Plecostomus: gold
התרשים הבא מייצג את הכיתה Shark
ואת הכיתה Plecostomus
, המשתייכות לסיווג האבסקטי, AquariumFish
.
שלב 2. יצירת ממשק
- ב-AquaiumFish.kt, יוצרים ממשק בשם
FishAction
בשיטהeat()
.
interface FishAction {
fun eat()
}
- יש להוסיף את
FishAction
לכל אחת מסיווגי המשנה ולהטמיע אתeat()
בהדפסת הדגים.
class Shark: AquariumFish(), FishAction {
override val color = "gray"
override fun eat() {
println("hunt and eat fish")
}
}
class Plecostomus: AquariumFish(), FishAction {
override val color = "gold"
override fun eat() {
println("eat algae")
}
}
- בפונקציית
makeFish()
, אפשר לבקש מכל הדגים שיצרת לאכול משהו על ידי קריאה ל-eat()
.
fun makeFish() {
val shark = Shark()
val pleco = Plecostomus()
println("Shark: ${shark.color}")
shark.eat()
println("Plecostomus: ${pleco.color}")
pleco.eat()
}
- מפעילים את התוכנית וצופים בפלט.
⇒ Shark: gray hunt and eat fish Plecostomus: gold eat algae
התרשים הבא מייצג את המחלקה Shark
ואת המחלקה Plecostomus
, ששתיהן מורכבות מהממשק של FishAction
ומטמיעות אותו.
מתי כדאי להשתמש בכיתות מופשטות לעומת בממשקים
הדוגמאות שלמעלה פשוטות, אבל כשיש לכם הרבה כיתות, ממשקים וממשקים מופשטים יכולים לעזור לכם לשמור על עיצוב נקי, מאורגן יותר וקל יותר לנהל אותו.
כפי שצוין למעלה, בכיתות מופשטות יכולים להיות בונים, והממשקים לא יכולים להיות שונים, אבל הם דומים מאוד. מתי כדאי להשתמש בכל אחד מהם?
כשאתם משתמשים בממשקים כדי לכתוב כיתה, הפונקציונליות של הכיתה מורחבת דרך מופעי הכיתות שהיא מכילה. לרוב, בעזרת יצירה מוזיקלית קל יותר להשתמש בקוד והסיבה לכך היא ירושה של כיתה מופשטת. בנוסף, אפשר להשתמש במספר ממשקים בכיתה, אבל אפשר לציין רק לכיתה אחת בלבד.
בדרך כלל, היצירה של יצירה מוזיקלית מובילה לקיבולות טובות יותר, לצימוד (תלות הדדית), לממשקים נקיים יותר ולקוד נוח יותר לשימוש. מסיבות אלה, שימוש בהרכב עם ממשקים הוא העיצוב המועדף. מצד שני, ירושה מכיתה מופשטת נוטה להתאים בצורה טבעית לבעיות מסוימות. לכן אתם מעדיפים להשתמש ביצירה מוזיקלית, אבל גם במקרה של ירושה, תוכלו להשתמש ב-Kotlin גם אתם.
- אם יש לך הרבה שיטות והטמעה אחת או שתיים של ברירת מחדל, כדאי להשתמש בממשק. לדוגמה:
AquariumAction
interface AquariumAction {
fun eat()
fun jump()
fun clean()
fun catchFish()
fun swim() {
println("swim")
}
}
- אפשר להשתמש בשיעור מופשט בכל פעם שלא משלימים כיתה. לדוגמה, בחזרה לכיתה
AquariumFish
אפשר להפוך את כל ההטמעה שלAquariumFish
ל-FishAction
, ולספק הטמעה שמוגדרת כברירת מחדל ב-eat
תוך שמירה על מופשט שלcolor
, כי אין צבע דגים כברירת מחדל.
interface FishAction {
fun eat()
}
abstract class AquariumFish: FishAction {
abstract val color: String
override fun eat() = println("yum")
}
המשימה הקודמת הצגה את הכיתות, הממשקים והרעיון של היצירה. הענקת גישה לממשק היא טכניקה מתקדמת שבה שיטות הממשק מוטמעות באמצעות אובייקט מסייע (או האצלה) המשמש לאחר מכן את הכיתה. אפשר להשתמש בטכניקה הזו כשמשתמשים בממשק של סדרה של כיתות לא קשורות: מוסיפים את הפונקציונליות של הממשק הנדרש למחלקת סיוע נפרדת, וכל אחת מהכיתות משתמשת במופע של מחלקת העזרה כדי להטמיע את הפונקציונליות.
במשימה הזו, צריך להקצות הרשאות לניהול כיתה.
שלב 1: יצירת ממשק חדש
- בAquaiumFish.kt, מסירים את הכיתה מ-
AquariumFish
. במקום לרשת את הכיתהAquariumFish
,Plecostomus
ו-Shark
יטמיעו ממשקים לפעולת הדגים ולצבע שלהם. - יש ליצור ממשק חדש,
FishColor
, שמגדיר את הצבע כמחרוזת.
interface FishColor {
val color: String
}
- יש לשנות את
Plecostomus
כדי להטמיע שני ממשקים,FishAction
וFishColor
. יש לעקוף אתcolor
מ-FishColor
ומ-eat()
מ-FishAction
.
class Plecostomus: FishAction, FishColor {
override val color = "gold"
override fun eat() {
println("eat algae")
}
}
- יש לשנות את הכיתה ב-
Shark
כדי ליישם גם את שני הממשקים,FishAction
וגםFishColor
, במקום לרשת מ-AquariumFish
.
class Shark: FishAction, FishColor {
override val color = "gray"
override fun eat() {
println("hunt and eat fish")
}
}
- הקוד הסופי אמור להיראות כך:
package example.myapp
interface FishAction {
fun eat()
}
interface FishColor {
val color: String
}
class Plecostomus: FishAction, FishColor {
override val color = "gold"
override fun eat() {
println("eat algae")
}
}
class Shark: FishAction, FishColor {
override val color = "gray"
override fun eat() {
println("hunt and eat fish")
}
}
שלב 2: יצירת כיתה יחידה
אחר כך מטמיעים את ההגדרה של החלק בהקצאת ההרשאות, על ידי יצירת כיתה של סיוע המטמיעה את FishColor
. אתם יוצרים כיתה בסיסית שנקראת GoldColor
שמטמיעה את FishColor
— היא מה שמופיע בה רק שצבעו הוא זהב.
לא הגיוני ליצור כמה מופעים של GoldColor
, כי כולם עושים בדיוק את אותו הדבר. לכן Kotlin מאפשר לך להצהיר על מחלקה שבה ניתן ליצור רק מופע אחד שלה על ידי שימוש במילת המפתח object
, במקום בclass
. Kotlin ייצור את המופע הזה ומכונה זו תאזכר אותו. לאחר מכן, כל שאר האובייקטים יוכלו להשתמש במופע הזה בלבד – אין דרך ליצור מופעים אחרים של הכיתה הזו. אם אתם מכירים את דפוס ה-Singleton, כך אתם מטמיעים סינגלטון בקוטלין.
- ב-AquaiumFish.kt, יוצרים אובייקט עבור
GoldColor
. שינוי הצבע.
object GoldColor : FishColor {
override val color = "gold"
}
שלב 3: הוספת הענקת גישה לממשק עבורדגי צבע
עכשיו אפשר להשתמש בהקצאת ממשק.
- ב-AquaiumFish.kt, יש להסיר את הכלל
color
מ-Plecostomus
. - יש לשנות את המחלקה
Plecostomus
כדי לקבל את הצבע שלה מ-GoldColor
. ניתן לעשות זאת על ידי הוספה שלby GoldColor
להצהרת הכיתה, כדי ליצור את הקצאת ההרשאות. פירוש הדבר הוא שבמקום להטמיעFishColor
, יש להשתמש בהטמעה שסופקה על ידיGoldColor
. לכן, בכל פעם שמתבצעת גישה ל-color
, הוא מיוחס ל-GoldColor
.
class Plecostomus: FishAction, FishColor by GoldColor {
override fun eat() {
println("eat algae")
}
}
עם הכיתה, כל פלקוס מוזהב, אבל הדגים האלה מגיעים בפועל בצבעים רבים. כדי לפתור את הבעיה הזו, אפשר להוסיף פרמטר constructor לצבע GoldColor
כצבע ברירת המחדל עבור Plecostomus
.
- יש לשנות את הכיתה ב-
Plecostomus
כדי לעבור ביןfishColor
עם המבנה שלה, ולהגדיר את ברירת המחדל ל-GoldColor
. שינוי הקצאת ההרשאות מ-by GoldColor
ל-by fishColor
.
class Plecostomus(fishColor: FishColor = GoldColor): FishAction,
FishColor by fishColor {
override fun eat() {
println("eat algae")
}
}
שלב 4: הוספת הענקת גישה לממשק עבורfishAction
באופן דומה, ניתן להשתמש בהקצאת ממשק עבור FishAction
.
- ב-AquaiumFish.kt יוצרים כיתה אחת (
PrintingFishAction
) שמטמיעה אתFishAction
. הכיתוב הואString
,food
ומדפיס את מה שהדגים אוכלים.
class PrintingFishAction(val food: String) : FishAction {
override fun eat() {
println(food)
}
}
- בכיתה
Plecostomus
, יש להסיר את פונקציית הביטולeat()
כי היא תחליף אותה בהענקת גישה. - בהצהרה של
Plecostomus
, יש להאציל אתFishAction
ל-PrintingFishAction
, ולאחר מכן להעביר את"eat algae"
. - בכל הקצאת ההרשאות, אין קוד בגוף של כיתה
Plecostomus
, לכן עליך להסיר את ה-{}
, מאחר שכל ההקצאות מטופלות על ידי הענקת גישה לממשק
class Plecostomus (fishColor: FishColor = GoldColor):
FishAction by PrintingFishAction("eat algae"),
FishColor by fishColor
התרשים הבא מייצג את הכיתות Shark
וה-Plecostomus
, שמורכבות מהממשקים של PrintingFishAction
ושל FishColor
, ומעניקות לו את ההטמעה.
האצלת ממשק היא יעילה, ובדרך כלל כדאי לשקול איך להשתמש בה בכל פעם שעושים שימוש בשיעור מופשט בשפה אחרת. היא מאפשרת להשתמש בקומפוזיציה כדי לחבר התנהגויות, במקום לדרוש סוגים רבים של תתי-כיתות, וכל אחת מהן מעוצבת באופן שונה.
סיווג נתונים דומה ל-struct
בשפות אחרות – הוא קיים בעיקר כדי לשמור נתונים מסוימים, אבל אובייקט של סיווג נתונים הוא עדיין אובייקט. לאובייקטים מסיווג נתונים ב-Kotlin יש כמה יתרונות נוספים, למשל, כלי הדפסה והעתקה. במשימה הזו יוצרים רמת נתונים פשוטה ולומדים על התמיכה שקוטלין מספקת לשיעורי נתונים.
שלב 1: יצירת סיווג נתונים
- מוסיפים חבילה חדשה
decor
במסגרת החבילה example.myapp ששומרת את הקוד החדש. לוחצים לחיצה ימנית על example.myapp בחלונית Project ובוחרים באפשרות File > New > Package. - בחבילה יש ליצור כיתה חדשה בשם
Decoration
.
package example.myapp.decor
class Decoration {
}
- כדי להפוך את
Decoration
לסיווג נתונים, יש להוסיף את הצהרת הכיתה למילות המפתחdata
. - אפשר להוסיף נכס
String
בשםrocks
כדי לתת לכיתה כמה נתונים.
data class Decoration(val rocks: String) {
}
- בקובץ, מחוץ לכיתה, יש להוסיף פונקציית
makeDecorations()
כדי ליצור ולהדפיס מופע שלDecoration
באמצעות"granite"
.
fun makeDecorations() {
val decoration1 = Decoration("granite")
println(decoration1)
}
- צריך להוסיף פונקציה
main()
כדי להתקשר אלmakeDecorations()
ולהפעיל את התוכנית. שימו לב לפלט הגיוני שנוצר כי זהו סיווג נתונים.
⇒ Decoration(rocks=granite)
- יוצרים ב-
makeDecorations()
אובייקטים נוספים מסוגDecoration
שמייצגים גם מירכאות וגם מירכאות, ומדפיסים אותם.
fun makeDecorations() {
val decoration1 = Decoration("granite")
println(decoration1)
val decoration2 = Decoration("slate")
println(decoration2)
val decoration3 = Decoration("slate")
println(decoration3)
}
- ב-
makeDecorations()
, מוסיפים הצהרת הדפסה שמדפיסה את התוצאה שמשווים ביןdecoration1
ל-decoration2
, והצהרה שנייה שמשווה ביןdecoration3
ל-decoration2
. צריך להשתמש בשיטה equals() שמסופקת על ידי מחלקות נתונים.
println (decoration1.equals(decoration2))
println (decoration3.equals(decoration2))
- מריצים את הקוד.
⇒ Decoration(rocks=granite) Decoration(rocks=slate) Decoration(rocks=slate) false true
שלב 2. שימוש בהרס
כדי להגיע למאפיינים של אובייקט נתונים ולהקצות אותם למשתנים, תוכלו להקצות אותם בנפרד.
val rock = decoration.rock
val wood = decoration.wood
val diver = decoration.diver
במקום זאת, תוכלו ליצור משתנים, אחד לכל נכס, ולהקצות את אובייקט הנתונים לקבוצת המשתנים. Kotlin מוסיף את ערך המאפיין לכל משתנה.
val (rock, wood, diver) = decoration
פעולה זו נקראת השחתה והיא קיצור דרך שימושי. מספר המשתנים צריך להתאים למספר הנכסים, והמשתנים מוקצים לפי סדר הופעתם בכיתה. הנה דוגמה מלאה שבאפשרותך לנסות ב-Decoration.kt.
// Here is a data class with 3 properties.
data class Decoration2(val rocks: String, val wood: String, val diver: String){
}
fun makeDecorations() {
val d5 = Decoration2("crystal", "wood", "diver")
println(d5)
// Assign all properties to variables.
val (rock, wood, diver) = d5
println(rock)
println(wood)
println(diver)
}
⇒ Decoration2(rocks=crystal, wood=wood, diver=diver) crystal wood diver
אם אין לך צורך באחד או יותר מהנכסים, ניתן לדלג עליהם באמצעות המאפיין _
במקום שם משתנה, כפי שמוצג בקוד שלמטה.
val (rock, _, diver) = d5
במשימה הזו תלמדו על כמה מהכיתות המיוחדות בקוטלין, כולל הנושאים הבאים:
- שיעורי סינגלטון
- Enum
- קורסים אטומים
שלב 1: ריקול כיתות לסינגל
חזרה על הדוגמה הקודמת עם הכיתה GoldColor
.
object GoldColor : FishColor {
override val color = "gold"
}
בגלל שכל מופע של GoldColor
מבצע את אותה פעולה, הוא הצהיר כ-object
במקום כ-class
לסינגל. יכול להיות רק מופע אחד שלו.
שלב 2: יצירת enum
קוטלין תומך גם ברשומות enums, שמאפשרות לכם לספר משהו ולתייחס אליו לפי שם, בדומה לשפות אחרות. כדי להצהיר מילים, יש להוסיף לקידומת את ההצהרה עם מילת המפתח enum
. להצהרת Enum בסיסית נדרשת רק רשימת שמות, אבל אפשר גם להגדיר שדה אחד או יותר המשויכים לכל שם.
- ב-Decoration.kt אפשר לנסות דוגמה של Enum.
enum class Color(val rgb: Int) {
RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF);
}
Enum הם קצת כמו לשון אחת – יכולה להיות רק אחת, ורק אחד מכל ערך בספירה. לדוגמה, יכול להיות רק Color.RED
אחד, Color.GREEN
אחד וColor.BLUE
אחד. בדוגמה הזו, ערכי ה-RGB מוקצים לנכס rgb
כדי לייצג את רכיבי הצבע. אפשר גם לקבל את הערך הסידורי של enum באמצעות המאפיין ordinal
, ואת השם שלו באמצעות המאפיין name
.
- כדאי לנסות דוגמה אחרת של enum.
enum class Direction(val degrees: Int) {
NORTH(0), SOUTH(180), EAST(90), WEST(270)
}
fun main() {
println(Direction.EAST.name)
println(Direction.EAST.ordinal)
println(Direction.EAST.degrees)
}
⇒ EAST 2 90
שלב 3: יצירת כיתה אטומה
כיתה אטומה היא מחלקה שניתן לסווג אותה מחדש, אבל רק בתוך הקובץ שבו היא מוצהרת. אם תנסו לסווג מחדש את הכיתה בקובץ אחר, תופיע שגיאה.
מאחר שהכיתות וסיווגי המשנה נמצאים באותו קובץ, קוטלין תכיר את כל כיתות המשנה באופן סטטי. כלומר, בזמן ההידור, המהדר רואה את כל הכיתות וכיתות המשנה, ומודע שכולן זהות, כך שהמהדר יכול לבצע בדיקות נוספות עבורכם.
- בAquaiumFish.kt, כדאי לנסות דוגמה של כיתה חתומה העוסקת בנושא הימי.
sealed class Seal
class SeaLion : Seal()
class Walrus : Seal()
fun matchSeal(seal: Seal): String {
return when(seal) {
is Walrus -> "walrus"
is SeaLion -> "sea lion"
}
}
לא ניתן לסווג מחדש את הכיתה Seal
בכיתה בקובץ אחר. אם רוצים להוסיף עוד Seal
סוגים, צריך להוסיף אותם באותו קובץ. כך, כיתות אטומות הן דרך בטוחה לייצג מספר קבוע של סוגים. לדוגמה, מחלקות אטומות הן דרך מצוינת להחזרת הצלחה או שגיאה מ-Network API.
השיעור הזה מכסה הרבה שטחים פתוחים. למרות שחלק גדול ממנה צריך להיות ידוע בשפות תכנות אחרות המיועדות לאובייקטים, Kotlin מוסיף מספר תכונות לשמירה על קוד תמציתי וקריא.
כיתות ובנאים
- הגדרת כיתה בקוטלין באמצעות
class
. - קוטלין יוצרת באופן אוטומטי ממירים סוגרים ונכסים.
- הגדירו את המבנה הראשי ישירות בהגדרת הכיתה. למשל:
class Aquarium(var length: Int = 100, var width: Int = 20, var height: Int = 40)
- אם קבלן ראשי זקוק לקוד נוסף, יש לכתוב אותו בבלוק
init
אחד או יותר. - מחלקה יכולה להגדיר בנאות משני אחד או יותר באמצעות
constructor
, אבל בסגנון Kotlin יש להשתמש בפונקציית מפעל במקום זאת.
הרשאות שינוי וסיווגי משנה
- כברירת מחדל, כל הכיתות והפונקציות ב-Kotlin הן
public
, אבל אפשר להשתמש בגורמי שינוי כדי לשנות את הרשאות הגישה ל-internal
,private
אוprotected
. - כדי ליצור מחלקת משנה, יש לסמן את מחלקת האב של
open
. - כדי לעקוף את השיטות ואת המאפיינים בתת-קבוצה, צריך לסמן את השיטות והמאפיינים
open
במחלקת ההורה. - אפשר לסווג סיווג לפי קטגוריות רק באותו קובץ שבו הוא מוגדר. כדי ליצור כיתה אטומה, יש להוסיף לפני ההצהרה את ההצהרה
sealed
.
מחלקות נתונים, טון יחיד ואנטום
- כדי ליצור מחלקת נתונים, מוסיפים את ההצהרה הבאה באמצעות
data
. - הריסה היא קיצור של הקצאת המאפיינים של אובייקט
data
למשתנים נפרדים. - אפשר ליצור כיתה יחידה באמצעות
object
במקוםclass
. - הגדרת enum באמצעות
enum class
.
שיעורים, ממשקים והענקת גישה מופשטים
- כיתות וממשקים מופשטים הם שתי דרכים לשיתוף התנהגות משותפת בין הכיתות.
- מחלקה מופשטת מגדירה נכסים והתנהגויות, אבל משאירה את ההטמעה בכיתות משנה.
- ממשק מגדיר התנהגות, והוא עשוי לספק הטמעות ברירת מחדל עבור חלק מההתנהגות, או עבור כולן.
- כשאתם משתמשים בממשקים כדי לכתוב כיתה, הפונקציונליות של הכיתה מורחבת דרך מופעי הכיתות שהיא מכילה.
- בהענקת גישה לממשק נעשה שימוש בהרכב, אך בנוסף נאציל את ההטמעה למחלקות הממשק.
- הרכב הוא דרך יעילה להוסיף פונקציונליות לכיתה באמצעות הענקת גישה לממשק. באופן כללי, רצוי ליצור קומפוזיציה, אבל ירושה של כיתה מופשטת מתאימה יותר לבעיות מסוימות.
התיעוד של Kotlin
אם אתם רוצים לקבל מידע נוסף על כל נושא בקורס הזה, או אם נתקעים, https://kotlinlang.org היא נקודת ההתחלה הטובה ביותר.
- כיתות וירושה
- יוצרים
- פונקציות במפעל
- נכסים ושדות
- משנים את החשיפה
- שיעורים מופשטים
- פלטפורמות
- הענקת גישה
- מחלקות נתונים
- שוויון
- השחתה
- הצהרות אובייקט
- כיתות אנום
- כיתות אטומות
- טיפול בשגיאות אופציונליות באמצעות כיתות שחוסמות קוטלין
מדריכים בקוטלין
האתר https://try.kotlinlang.org כולל מדריכים עשירים בשם Kotlin Koans, מתורגמן מבוסס-אינטרנט וסדרה מלאה של מסמכי עזר עם דוגמאות.
קורס של Udacity
כדי להציג את הקורס של Udacity בנושא זה, ניתן לעיין ב-Kotlin Bootcamp for Programmers.
IntelliJ IDEA
ניתן למצוא תיעוד עבור IntelliJ IDEA באתר JetBrains.
בקטע הזה מפורטות מטלות שיעורי בית אפשריות לתלמידים שעובדים עם קוד Lab הזה, במסגרת קורס בהדרכת מורה. למורה יש אפשרות לבצע את הפעולות הבאות:
- אם צריך, מקצים שיעורי בית.
- ספרו לתלמידים איך מגישים מטלות בשיעורי בית.
- לתת ציונים למטלות שיעורי הבית.
המורים יכולים להשתמש בהצעות האלה כמה שפחות, ומומלץ להקצות להן כל שיעורי בית שדעתם מתאימה להם.
אם אתם עובדים בעצמכם על שיעור הקוד הזה, אתם מוזמנים להשתמש במטלות שיעורי הבית האלה כדי לבחון את הידע שלכם.
מענה על השאלות האלה
שאלה 1
בכיתות יש שיטה מיוחדת שמשמשת כתרשים ליצירת אובייקטים של הכיתה. איזו שיטה נקראת?
הוספה של כלי בנייה
▬ אנימציה
▬ בנאי
▬ שרטוט
שאלה 2
אילו מההצהרות הבאות לגבי ממשקים וכיתות מופשטות אינן נכונות?
הוספה של שיעורי מופשטים יכולים להיות בנאים.
▬ בממשקים לא יכולים להיות בנאים.
▬ ממשקים וכיתות אבסטרקטיות יכולים להיות מוצגים במדויק.
הוספה של מאפיינים מופשטים צריכה להתבצע על ידי מחלקות משנה של המחלקה המופשטת.
שאלה 3
איזו מהאפשרויות הבאות אינה שינוי של מידת החשיפה של Kotlin עבור נכסים, שיטות וכו'?
▬ internal
▬ nosubclass
▬ protected
▬ private
שאלה 4
צריך להתחשב במחלקת הנתונים הזו:data class Fish(val name: String, val species:String, val colors:String)
אילו מהקודים הבאים לא חוקיים כדי ליצור ולהרוס אובייקט Fish
?
▬ val (name1, species1, colors1) = Fish("Pat", "Plecostomus", "gold")
▬ val (name2, _, colors2) = Fish("Bitey", "shark", "gray")
▬ val (name3, species3, _) = Fish("Amy", "angelfish", "blue and black stripes")
▬ val (name4, species4, colors4) = Fish("Harry", "halibut")
שאלה 5
נניח שיש לך גן חיות עם המון בעלי חיים, שכולם צריכים לטפל בהם. אילו מהנושאים הבאים לא יהיו חלק מיישום התוכנית?
▬ interface
עם סוגים שונים של מנות בעלי חיים.
▬ כיתה אחת (abstract Caretaker
) שממנה אפשר ליצור סוגים שונים של מטפלים.
▸interface
כדי לתת מים נקיים לבעלי חיים.
▬ כיתה אחת (data
) עבור רשומה בלוח זמנים של פידים.
המשך לשיעור הבא:
סקירה כללית של הקורס, כולל קישורים למעבדות קוד אחרות, זמינה במאמר "Kotlin Bootcamp for Programmers: ברוך הבא לקורס."