14-bo‘lim

Kengaytma funksiyalari

Mavjud turga o'z funksiyangizni qo'shish, kengaytma xossalari, nega ular statik bog'lanadi va operator hamda infiks shakllari.

🕑 13 daqiqa o‘qish 📄 645 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Birinchi kengaytma
  2. Nima uchun kerak
  3. Kengaytma xossalari
  4. Kengaytmalar statik bog'lanadi
  5. A'zo metod ustun keladi
  6. Null bo'lishi mumkin bo'lgan turga
  7. Kengaytmaning ko'rinishi
  8. infix
  9. Operatorlarni qayta yozish
  10. Qayerda e'lon qilish
  11. Xulosa

Kengaytma - Kotlin ning eng o'ziga xos imkoniyatlaridan biri: mavjud turga o'z funksiyangizni qo'shish. Uning kodiga tegmasdan va merosga ham kirmasdan.

Birinchi kengaytma #

KOTLIN
fun String.birinchiHarfKatta(): String =
    if (isEmpty()) this else this[0].uppercase() + substring(1)

fun Int.kvadrat(): Int = this * this

fun main() {
    println("malika".birinchiHarfKatta())
    println("".birinchiHarfKatta())
    println(7.kvadrat())
}
Natija
Malika

49

Shakli: fun Tur.nom(): Natija. Funksiya ichida this - chaqirilgan obyekt (ko'pincha uni yozmasa ham bo'ladi).

Endi "matn".birinchiHarfKatta() deb yozish mumkin - go'yo bu String ning o'z metodi.

Nima uchun kerak #

KOTLIN
fun List<Int>.ortacha(): Double =
    if (isEmpty()) 0.0 else sum().toDouble() / size

fun String.faqatRaqamlar(): String = filter { it.isDigit() }

fun Int.soatgaAylantir(): String = "%02d:%02d".format(this / 60, this % 60)

fun main() {
    println(listOf(85, 92, 78).ortacha())
    println(emptyList<Int>().ortacha())
    println("+998 (90) 123-45-67".faqatRaqamlar())
    println(145.soatgaAylantir())
}
Natija
85.0
0.0
998901234567
02:25

Uchala holatda ham biz o'zimiz yozmagan turlarga - List, String, Int - foydali funksiya qo'shdik.

Kengaytma - o'qishni yaxshilaydi

Ikkalasini solishtiring:

KOTLIN
soatgaAylantir(ortacha(ballar.filter { it > 60 }))
KOTLIN
ballar.filter { it > 60 }.ortacha().soatgaAylantir()

Ikkinchisi chapdan o'ngga, ish bajarilish tartibida o'qiladi. Birinchisida esa ichkaridan tashqariga qarab o'qish kerak.

Kotlin standart kutubxonasining katta qismi aynan shu sababdan kengaytma sifatida yozilgan.

Kengaytma xossalari #

KOTLIN
val String.ikkinchiHarf: Char?
    get() = if (length >= 2) this[1] else null

val <T> List<T>.ikkinchisi: T?
    get() = if (size >= 2) this[1] else null

val Int.juftmi: Boolean
    get() = this % 2 == 0

fun main() {
    println("Kotlin".ikkinchiHarf)
    println("K".ikkinchiHarf)
    println(listOf(10, 20, 30).ikkinchisi)
    println(4.juftmi)
    println(7.juftmi)
}
Natija
o
null
20
true
false

Kengaytma xossasida saqlash joyi yo'q - shuning uchun u faqat get() bilan yoziladi va har chaqirilganda hisoblanadi.

Kengaytmalar statik bog'lanadi #

Bu eng muhim tafsilot:

KOTLIN
open class Hayvon
class It : Hayvon()

fun Hayvon.ovoz() = "noma'lum ovoz"
fun It.ovoz() = "Vov-vov!"

fun main() {
    val it: It = It()
    val hayvon: Hayvon = It()

    println(it.ovoz())
    println(hayvon.ovoz())
}
Natija
Vov-vov!
noma'lum ovoz
Kengaytma - haqiqiy metod emas

Ikkinchi natijaga diqqat qiling. hayvon o'zgaruvchisida It obyekti turibdi, lekin Hayvon.ovoz() chaqirildi.

Sababi: kengaytmalar e'lon qilingan turga qarab tanlanadi, ichida nima turganiga emas. Ular sinfga qo'shilmaydi - kompilyator ularni oddiy funksiya chaqiruviga aylantiradi.

Ya'ni bu yerda polimorfizm ishlamaydi. Xatti-harakat turga qarab o'zgarishi kerak bo'lsa - haqiqiy metod va override ishlating.

Kengaytma - qulaylik vositasi, vorislik o'rnini bosuvchi emas.

A'zo metod ustun keladi #

KOTLIN
class Quti {
    fun salom() = "a'zo metod"
}

fun Quti.salom() = "kengaytma"

fun main() {
    println(Quti().salom())
}
Natija
a'zo metod

Agar sinfda shu nomli metod bo'lsa, u chaqiriladi. Kengaytma mavjud metodni "o'g'irlab" ololmaydi - bu xavfsizlik kafolati.

Null bo'lishi mumkin bo'lgan turga #

KOTLIN
fun String?.xavfsizUzunlik(): Int = this?.length ?: 0

fun String?.boshMi(): Boolean = this == null || this.isBlank()

fun main() {
    val bor: String? = "matn"
    val yoq: String? = null

    println(bor.xavfsizUzunlik())
    println(yoq.xavfsizUzunlik())
    println(yoq.boshMi())
    println("  ".boshMi())
    println("x".boshMi())
}
Natija
4
0
true
true
false

String? ga kengaytma yozsangiz, uni null ustida ham chaqirish mumkin - ?. kerak emas. Standart kutubxonadagi isNullOrBlank() aynan shunday ishlaydi.

Kengaytmaning ko'rinishi #

KOTLIN
class Hisob(private val qoldiq: Int) {
    fun ochiqQoldiq() = qoldiq
}

fun Hisob.yetarlimi(summa: Int): Boolean = ochiqQoldiq() >= summa

fun main() {
    val h = Hisob(500000)
    println(h.yetarlimi(200000))
    println(h.yetarlimi(900000))
}
Natija
true
false
Kengaytma yashirin a'zolarni ko'rmaydi

Yuqorida ochiqQoldiq() ishlatildi, chunki qoldiq xossasi private.

Kengaytma sinfning tashqarisida turadi, shuning uchun u faqat ochiq a'zolarga kira oladi. Bu mantiqiy: aks holda inkapsulyatsiyani istalgan odam buzib qo'yardi.

infix #

KOTLIN
infix fun Int.gacha(oxiri: Int): List<Int> = (this..oxiri).toList()

data class Nuqta(val x: Int, val y: Int)

infix fun Nuqta.qoshish(boshqa: Nuqta) = Nuqta(x + boshqa.x, y + boshqa.y)

fun main() {
    println(1 gacha 5)
    println(Nuqta(1, 2) qoshish Nuqta(3, 4))

    println(1.gacha(5))
}
Natija
[1, 2, 3, 4, 5]
Nuqta(x=4, y=6)
[1, 2, 3, 4, 5]

infix - nuqtasiz va qavssiz yozish imkonini beradi. Shartlari: bitta parametr, standart qiymat yo'q.

to ham aynan shunday funksiya - shuning uchun "a" to 1 deb yozilardi.

Operatorlarni qayta yozish #

KOTLIN
data class Pul(
    val miqdor: Int,
    val valyuta: String = "so'm"
) : Comparable<Pul> {
    operator fun plus(boshqa: Pul) = Pul(miqdor + boshqa.miqdor, valyuta)
    operator fun times(son: Int) = Pul(miqdor * son, valyuta)

    override fun compareTo(other: Pul) = miqdor.compareTo(other.miqdor)

    override fun toString() = "$miqdor $valyuta"
}

fun main() {
    val a = Pul(50000)
    val b = Pul(30000)

    println(a + b)
    println(a * 3)
    println(a > b)
    println(listOf(a, b).max())
}
Natija
80000 so'm
150000 so'm
true
50000 so'm
OperatorFunksiya nomi
+plus
-minus
*times
/div
[i]get
incontains
> <compareTo
compareTo uchun Comparable ni bajaring

operator fun compareTo ni shunchaki yozsangiz, > va < ishlaydi - lekin max(), min() va sorted() ishlamaydi.

Sababi: bu funksiyalar turdan Comparable<T> interfeysini bajarishni talab qiladi, faqat operator borligi yetarli emas.

Shuning uchun yuqoridagi misolda : Comparable<Pul> yozilgan va compareTo override bilan belgilangan. Bu holatda operator so'zini yozish shart emas - u interfeysdan meros bo'lib o'tadi.

Operatorlarni ehtiyot bilan

Pul + Pul tabiiy o'qiladi. Lekin Talaba + Talaba nima degani?

Operatorni faqat ma'nosi aniq va bir xil tushuniladigan bo'lsa qayta yozing. Shubhalansangiz - oddiy nomli metod yozing: a.qoshish(b) hech kimni chalkashtirmaydi.

Qayerda e'lon qilish #

KOTLIN
fun String.toza(): String = trim().lowercase()

class Hisobot {
    fun Int.formatla(): String = "%,d".format(this)

    fun chiqar(summa: Int) = "Summa: ${summa.formatla()}"
}

fun main() {
    println("  SALOM  ".toza())
    println(Hisobot().chiqar(1500000))
}
Natija
salom
Summa: 1,500,000

Kengaytmani fayl darajasida (hamma joydan ko'rinadi) yoki sinf ichida (faqat o'sha sinfda) e'lon qilish mumkin.

Amaliy topshiriq
  1. String ga birinchiHarfKatta() kengaytmasini yozing.
  2. Int ga kub() kengaytmasini qo'shing.
  3. List<Int> ga ortacha() yozing va bo'sh ro'yxatda sinang.
  4. Kengaytma xossasi bilan oxirgiHarf ni qaytaring.
  5. Ota va voris turlarga bir xil nomli kengaytma yozib, qaysi biri chaqirilishini tekshiring.
  6. Sinfdagi metod bilan bir xil nomli kengaytma yozing.
  7. String? ga kengaytma yozib, null ustida chaqiring.
  8. infix funksiya yozing.
  9. data class ga plus operatorini qo'shing.
  10. Telefon raqamidan faqat raqamlarni ajratuvchi kengaytma yozing.

Xulosa #

  • fun Tur.nom() - mavjud turga funksiya qo'shadi; this - chaqirilgan obyekt.
  • Kengaytma zanjirni chapdan o'ngga o'qishli qiladi.
  • Kengaytma xossasida saqlash joyi yo'q - faqat get().
  • Kengaytmalar statik bog'lanadi: e'lon qilingan turga qarab tanlanadi, polimorfizm ishlamaydi.
  • Sinfdagi a'zo metod ustun keladi.
  • Tur? ga kengaytma null ustida ham chaqiriladi.
  • Kengaytma yashirin a'zolarni ko'rmaydi.
  • infix nuqtasiz yozishga, operator esa + kabi belgilarga imkon beradi - ikkalasini ham o'lchov bilan ishlating.

Keyingi bo'limda lambda va qamrov funksiyalarini ko'ramiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.