במדריך זה, נדבר על מושגי תכנות מונה של Kotlin. נדבר בפרט על Class ב-Kotlin. נסתכל גם על בנאי Kotlin, מגבלי גישה ו-Class אבסטרקטית.
Class ב-Kotlin
קבוצת פונקציות ומאפיינים מוגדרים בתוך תבנית כחולה. ב-Kotlin, Class מוגדרת באמצעות מילת המפתח
class
ואחריה שם ה-Class. הגוף הולך בתוך סוגריים מסולסלים.
class FirstClass {
}
המופע של ה-Class משולש באופן הבא:
val firstClass = FirstClass()
var new = FirstClass() //here new is the name of the var.
בניגוד ל-Java, new
אינה מילת מפתח ב-Kotlin. Class ב-Kotlin ברירת מחדל הם final. לכן, המקביל של ההגדרות לעיל ב-Java ייראה כמו כן:
public final class FirstClass {
}
לכן, כברירת מחדל, Class ב-Kotlin אינם ניתנים לירושה. כדי להפוך Class לא סופי יש להוסיף את מילת המפתח open
.
open class Me{
}
האנוטציה open
מאפשרת לאחרים לירש מ-Class זו.
דוגמה על Class ב-Kotlin
בואו ניצור מחלקה עם מספר פונקציות ומאפיין. נראה איך לגשת לפונקציות ולמאפיינים של המחלקה הזו. בנוסף, נראה איך להגדיר מאפייני חבר.
class User {
var loggedIn: Boolean = false
val cantChangeValue = "Hi"
fun logOn() {
loggedIn = true
}
fun logOff() {
loggedIn = false
}
}
fun main(args: Array<String>) {
val user = User()
println(user.loggedIn) //false
user.logOn()
println(user.loggedIn) //true
user.logOff()
println(user.loggedIn) //false
user.cantChangeValue = "Hey" //won't compile. Can't modify a final variable.
}
הפונקציה main
שייכת למחלקה Test.kt
. כדי לגשת לחברים ולפונקציות, עלינו להשתמש באופרטור הנקודה. מאפיין val
לא יכול להיות מוגדר שוב באמצעות אופרטור הנקודה.
Kotlin init
לבלוק האתחול של Kotlin מוגדר כפי שמוצג למטה.
class User {
init{
print("Class instance is initialised.")
}
var loggedIn: Boolean = false
val cantChangeValue = "Hi"
fun logOn() {
loggedIn = true
}
fun logOff() {
loggedIn = false
}
}
הקוד בתוך הבלוק init
הוא הראשון שיתבצע כאשר המחלקה מתווצרת. בלוק init
יופעל בכל פעם שהמחלקה מתווצרת, עם כל סוג של בנאי כמו שנראה אחר כך. ניתן לכתוב מספר בלוקי אתחול במחלקה. הם יופעלו בסדר כפי שמוצג למטה.
class MultiInit(name: String) {
init {
println("First initializer block that prints ${name}")
}
init {
println("Second initializer block that prints ${name.length}")
}
}
fun main(args: Array) {
var multiInit = MultiInit("Kotlin")
}
//הודפס בלוג בקונסול.
//בלוק אתחול ראשון שמדפיס Kotlin
//בלוק אתחול שני שמדפיס 6
מחלקות Kotlin מאפשרות להדפיס מאפיינים בהגדרה עצמה על ידי שימוש בפונקציה also
כפי שמוצג למטה.
class MultiInit(name: String) {
val firstProperty = "First property: $name".also(::println)
init {
println("First initializer block that prints ${name}")
}
val secondProperty = "Second property: ${name.length}".also(::println)
init {
println("Second initializer block that prints ${name.length}")
}
}
fun main(args: Array) {
var multiInit = MultiInit("Kotlin")
}
//הודפס.
//מאפיין ראשון: Kotlin
//בלוק אתחול ראשון שמדפיס Kotlin
//מאפיין שני: 6
//בלוק אתחול שני שמדפיס 6
בנאי Kotlin
בנאים ב-Kotlin הם פונקציות חבר מיוחדות המשמשות לאתחול תכונות. בנאים ב-Kotlin נכתבים ומאורגנים בצורה שונה מ-Java. כברירת מחדל, לכל מחלקה יש בנאי ריק כפי שמוצג למטה:
class Student {
var name: String
val age : Int
init {
name = "Anupam"
age = 24
}
init {
name = "Anupam Chugh"
//age = 26
}
}
fun main(args: Array) {
val student = Student()
println("${student.name} age is ${student.age}")
student.name = "Your"
//student.age = 26 //לא יתרגם. age הוא val
println("${student.name} age is ${student.age}")
}
//הדפסה בקונסול:
//Anupam Chugh גילו הוא 24
//גילך הוא 24
בנאים ראשיים
בנאים ראשיים ב-Kotlin מוגדרים ישירות בכותרת המחלקה כפי שמוצג למטה.
class User(var name: String, var isAdmin: Boolean) {
init {
name = name + " @ JournalDev.com"
println("Author Name is $name. Is Admin? $isAdmin")
}
}
הגדרת בנאי הראשי נכנסת לתוך כותרת המחלקה. הגדרנו את סוגי המאפיינים (val/var) בתוך הבנאי עצמו. שים לב: אלא אם כן צוין כ-var
, לברירת מחדל, ארגומנטים של הבנאי הם val
.
class User(name: String, isAdmin: Boolean)
בקוד למעלה, שם ו-isAdmin לא יכולים להיות משוייכים מחדש. כאחלה, נוכל גם להקצות את ארגומנטי הבנאי לתכונות החבר במחלקה כפי שמוצג למטה.
class User(name: String, val isAdmin: Boolean) {
var username = name
val _isAdmin = isAdmin
init {
username= username + " @ JournalDev.com"
println("Author Name is $name. Is Admin? $_isAdmin")
}
}
fun main(args: Array) {
var user = User("Anupam",false)
user.isAdmin = true //won't compile since isAdmin is val
user._isAdmin = true //won't compile. Same reason.
user = User("Pankaj",true)
}
//הדפסה בלוג הקונסול:
//שם המחבר הוא Anupam. האם הוא מנהל? לא
//שם המחבר הוא Pankaj. האם הוא מנהל? כן
ערכי ברירת מחדל של בנאי Kotlin
ב-Kotlin ניתן לציין ערכי ברירת מחדל בבנאי עצמו כפי שמוצג למטה.
class User(name: String, var website: String = "JournalDev") {
init {
println("Author $name writes at $website")
}
init {
website = website + ".com"
println("Author $name writes at $website")
}
}
fun main(args: Array) {
var user = User("Anupam","JournalDev")
user = User("Pankaj","JournalDev")
}
// המשמעות מודפסת על המסך:
// המחבר אנופם כותב ב-JournalDev
// המחבר אנופם כותב ב-JournalDev.com
// המחבר פנקאג' כותב ב-JournalDev
// המחבר פנקאג' כותב ב-JournalDev.com
בנאי משני
בנאים משניים נכתבים בתוך גוף המחלקה על ידי הוספת המילה המפתחית constructor
. הדוגמה הבאה מדגימה זאת.
class Student {
var name: String
val age : Int
constructor(name: String, age: Int)
{
this.name = name
this.age = age
}
fun printDetails()
{
println("Name is $name and Age is $age")
}
}
fun main(args: Array) {
var student = Student("Anupam", 24)
student.printDetails()
}
// המשמעות מודפסת על המסך:
// השם הוא אנופם והגיל הוא 24
השימוש הנפוץ ביותר בבנאים משניים הוא במחלקות משנה כאשר יש צורך לאתחל את המחלקה בדרכים שונות. אם במחלקה קיים בנאי ראשי, הבנאי המשני חייב להתייחס אליו בהצהרתו. ההצהרה נעשית באמצעות המילה המפתחית this
.
class Student(var name: String, val age: Int) {
var skill: String
init {
skill = "NA"
}
constructor(name: String, age: Int, skill: String) : this(name, age) {
this.skill = skill
}
fun printDetails() {
if (skill.equals("NA"))
println("Name is $name and Age is $age")
else
println("Name is $name and Age is $age Skill is $skill")
}
}
// המשמעות מודפסת בלוג:
// השם הוא אנופם והגיל הוא 24
// השם הוא אנופם והגיל הוא 24 Skill is Kotlin
בלוק init
משמש לאתחול של חבר המאפיין skill
. הבנאי המשני מפנה לבנאי הראשי באמצעות : this
.
גטרים וסטרים מותאמים אישית
עד כה, נגשנו ושינינו מאפיינים במחלקה באמצעות אופרטור הנקודה על מופע המחלקה. בואו נשתמש בתחבירי set
ו־get
כדי לראות איך אפשר להתאים אישית את הגישה.
class Name{
var post: String = "default"
set(value) {if(!post.isNotEmpty()) {
throw IllegalArgumentException(" Enter a valid name")
}
field = value
print(value)
}
}
fun main(args: Array<String>) {
var name = Name()
name.post = "Kotlin Classes"
name.post = ""
name.post = "Kotlin Data Classes Our Next Tutorial"
}
הדפס בלוג כולל את הבא:
Kotlin Classes
Exception in thread "main" java.lang.IllegalArgumentException: Enter a valid name
at Name.setPost(Test.kt:16)
at TestKt.main(Test.kt:78)
משתנה ה־field
במטמון שומר על הערך הישן. בואו נוסיף גם פונקציה לקבלת ערך.
class Name{
var post: String = "default"
set(value) {if(!post.isNotEmpty()) {
throw IllegalArgumentException(" Enter a valid name")
}
field = value
}
get() {
return field.capitalize()
}
}
fun main(args: Array) {
var name = Name()
name.post = "kotlin classes"
println(name.post)
name.post = "kotlin data Classes our next Tutorial"
println(name.post)
}
//הדפס נוסף במהלך הביצוע:
//מחלקות Kotlin
//מחלקות נתונים Kotlin - הדרכה הבאה שלנו
capitalize()
משנה את האות הראשונה של המחרוזת לאות גדולה. הערה: אם המאפיין הוא val
, פעולת ה־set
לא תהיה קומפיל.
מודיפיקטורי הראיון של Kotlin
- ציבורי: כל מחלקה, פונקציה, מאפיין, ממשק או אובייקט המכיל את המודיפיקטור הזה נראה ונגיש מכל מקום.
- פרטי: קובץ/פונקציה הוגדרו עם מודיפייר זה יכולים להיכנס רק באותו קובץ. חבר/מאפיין בקובץ/פונקציה עם מודיפייר זה יכולים להיכנס רק בתוך הבלוק הזה.
- מוגן: מודיפייר זה זהה לפרטי, רק שהוא מאפשר גישה וראות בתת-מחלקות.
- פנימי: קובץ/ממשק/פונקציה עם מודיפייר זה נגיש רק בתוך אותו מודול.
מודיפיירים לראות גם בבנאי. הקצאת מודיפייר לבנאי ראשי מחייבת אותנו לציין את המילה המפתחת constructor
לצד הבנאי בכותרת המחלקה.
class Student private constructor (var name: String, val age: Int) {
var skill: String
init {
skill = "NA"
}
constructor(name: String, age: Int, skill: String) : this(name, age) {
this.skill = skill
}
fun printDetails() {
if (skill.equals("NA"))
println("Name is $name and Age is $age")
else
println("Name is $name and Age is $age Skill is $skill")
}
}
fun main(args: Array) {
var student = Student("Anupam",24,"Kotlin")
student.printDetails()
}
//prints
//השם הוא אנופם והגיל הוא 24, המיומנות היא Kotlin
בנאי פרטי אינו יכול להיקרא מחוץ לקובץ. בקוד לעיל, נוכל ליצור את המחלקה בפונקציה שונה רק באמצעות בנאי משני.
מחלקה אבסטרקטית ב-Kotlin
כמו ב-Java, מילת המפתח abstract
משמשת להגינוי של מחלקות אבסטרקטיות ב-Kotlin. מחלקה אבסטרקטית אינה יכולה להיצור ישירות, אך יש אפשרות לשוחזר אותה על ידי מחלקות מורשות. ללא ציון נוסף, החברים של מחלקה אבסטרקטית הם לא אבסטרקטיים.
abstract class Person(name: String) {
init {
println("Abstract Class. init block. Person name is $name")
}
abstract fun displayAge()
}
class Teacher(name: String): Person(name) {
var age : Int
init {
age = 24
}
override fun displayAge() {
println("Non-abstract class displayAge function overridden. Age is $age")
}
}
fun main(args: Array) {
val person = Teacher("Anupam")
person.displayAge()
}
//הדפסה בקונסול:
//מחלקה אבסטרקטית. בלוק init. שם האדם הוא אנופם
//מחלקה לא אבסטרקטית. הגיל הוא 24
הערה: כיתות המופעלות נפתחות כבר כברירת מחדל. לכן, להוסיף את המילה השמורה "open" כדי לאפשר תת-קבוצות אינו נדרש. מילת המפתח "override" משמשת לדריסת שיטה בתת-קבוצה. כבר כיסינו את היסודות של כיתות Kotlin במדריך זה. עדיין יש עוד הרבה דברים כמו כיתות נתונים, כיתות מוחתמות, ירושה וכו '. אנו נכסה אותם במדריכים הבאים. מקורות: Kotlin Docs
Source:
https://www.digitalocean.com/community/tutorials/kotlin-class-constructor