Darsliklar Go Lang Interface

Go Lang Go Lang Interface

Interface — Go’da polimorfizmning asosi. Boshqa ko’p tillardan (Java, C++) farqli, Go’da interfeysni aniq “amalga oshiraman” deb e’lon qilish shart emas — tur interfeysdagi barcha metodlarga ega bo’lsa, u avtomatik shu interfeysni qanoatlantiradi.

Interfacebir yoki bir nechta metod imzosini o’z ichiga olgan tur. Har qanday konkret tur, agar shu metodlarni amalga oshirsa, “e’lon qilinmasdan” shu interfeysga mos keladi — bu yashirin (implicit) qanoatlantirish deb ataladi.

Interfeys e’lon qilish va yashirin qanoatlantirish

package main

import "fmt"

type Shakl interface {
    Yuza() float64
}

type Tortburchak struct {
    Kengligi, Balandligi float64
}

func (t Tortburchak) Yuza() float64 {
    return t.Kengligi * t.Balandligi
}

type Doira struct {
    Radius float64
}

func (d Doira) Yuza() float64 {
    return 3.14159 * d.Radius * d.Radius
}

func chiqar(s Shakl) {
    fmt.Println(s.Yuza())
}

func main() {
    t := Tortburchak{Kengligi: 5, Balandligi: 3}
    d := Doira{Radius: 2}

    chiqar(t)
    chiqar(d)
}
15
12.56636

Tortburchak va Doira — hech qayerda "men Shakl interfeysini amalga oshiraman" deb yozilmagan. Ular shunchaki Yuza() float64 metodiga ega, shu sabab ikkalasi ham avtomatik Shakl interfeysiga mos keladi. chiqar(s Shakl) funksiyasi esa aniq turni bilmasdan, faqat Yuza() metodiga tayanib ishlaydi.

Nega bu foydali — yangi tur qo’shish

Interfeysning asosiy kuchi: mavjud kodni o’zgartirmasdan, yangi tur qo’shish mumkin — u faqat kerakli metodga ega bo’lsa, darhol ishlay boshlaydi:

package main

import "fmt"

type Shakl interface {
    Yuza() float64
}

type Uchburchak struct {
    Asos, Balandlik float64
}

func (u Uchburchak) Yuza() float64 {
    return u.Asos * u.Balandlik / 2
}

func chiqar(s Shakl) {
    fmt.Println(s.Yuza())
}

func main() {
    u := Uchburchak{Asos: 10, Balandlik: 4}
    chiqar(u)
}
20

chiqar funksiyasi bitta ham o’zgartirilmadi — yangi Uchburchak turi Yuza() metodini olgan zahoti, avvaldan yozilgan chiqar bilan muammosiz ishladi.

Bo’sh interfeys — istalgan turni qabul qilish

interface{} (yoki zamonaviy Go’da uning taxallusi any) — hech qanday metod talab qilmaydi, shuning uchun istalgan turdagi qiymatni qabul qiladi:

package main

import "fmt"

func chiqar(qiymat any) {
    fmt.Println(qiymat)
}

func main() {
    chiqar(42)
    chiqar("UzbekDevs")
    chiqar(3.14)
    chiqar(true)
}
42
UzbekDevs
3.14
true

anyinterface{}ning Go 1.18’dan beri qo’shilgan qulay taxallusi. U qiymatning turi haqida hech narsa bilmaydi, shuning uchun uni ishlatishdan oldin odatda keyingi darsda ko’radigan type assertion kerak bo’ladi.

Bir nechta metodli interfeys

Interfeys bir nechta metodni talab qilishi mumkin — turi ularning barchasiga ega bo’lgandagina interfeysga mos keladi:

package main

import "fmt"

type Hisobotchi interface {
    Sarlavha() string
    Matn() string
}

type Buyurtma struct {
    ID int
}

func (b Buyurtma) Sarlavha() string {
    return fmt.Sprintf("Buyurtma #%d", b.ID)
}

func (b Buyurtma) Matn() string {
    return "Holat: yetkazilmoqda"
}

func chopEt(h Hisobotchi) {
    fmt.Println(h.Sarlavha())
    fmt.Println(h.Matn())
}

func main() {
    b := Buyurtma{ID: 501}
    chopEt(b)
}
Buyurtma #501
Holat: yetkazilmoqda

Buyurtma Hisobotchi interfeysiga mos kelishi uchun ikkala metodni ham (Sarlavha va Matn) amalga oshirishi shart edi — agar faqat bittasi yozilganda, chopEt(b) chaqiruvi kompilyatsiya xatosi berardi.