Interfeyslar
Go dasturlash tilida interfeys (interface) — bu faqat metodlar imzosi (nomi, parametrlari va qaytarish turi) keltirilgan, lekin ularning tanasi (bajarilishi) yozilmagan maxsus turdir.
Interfeys qandaydir vazifani bajarish qoidasini (shartnomasini) belgilaydi. Uni amalda qo'llash uchun esa strukturalar (struct) ushbu metodlarning tanasini yozishi kerak.
type Shape interface {
area() float32
perimeter() float32
}
Bu yerda Shape interfeysi ikkita metodni belgilaydi: area() va perimeter().
Go tilida boshqa tillardagi kabi implements kalit so'zi ishlatilmaydi. Agar biror struktura interfeysdagi barcha metodlarni o'zida aniqlasa, u avtomatik ravishda ushbu interfeysni amalga oshirgan (implement qilgan) hisoblanadi (bunga implicit implementation deyiladi).
Rectangle strukturasi orqali Shape interfeysini amalga oshirishpackage main
import "fmt"
// Interfeys e'lon qilamiz
type Shape interface {
area() float32
}
// Interfeysni amalga oshiruvchi struktura
type Rectangle struct {
length, breadth float32
}
// Rectangle uchun area() metodini yozamiz
func (r Rectangle) area() float32 {
return r.length * r.breadth
}
// Interfeysni qabul qiluvchi funksiya
func calculate(s Shape) {
fmt.Println("Yuzasi:", s.area())
}
func main() {
rect := Rectangle{7, 4}
// rect ni calculate funksiyasiga uzatamiz
calculate(rect)
}
Natija:
Yuzasi: 28
Bu yerda Rectangle strukturasi area() metodiga ega bo'lgani sababli, calculate(s Shape) funksiyasi uni bemalol Shape sifatida qabul qila oladi.
Interfeyslarning eng kuchli tomoni shundaki, bitta umumiy interfeysdan bir nechta turli xil strukturalar foydalanishi mumkin:
package main
import "fmt"
type Shape interface {
area() float32
}
// 1. To'rtburchak strukturasi
type Rectangle struct {
length, breadth float32
}
func (r Rectangle) area() float32 {
return r.length * r.breadth
}
// 2. Uchburchak strukturasi
type Triangle struct {
base, height float32
}
func (t Triangle) area() float32 {
return 0.5 * t.base * t.height
}
// Umumiy interfeys orqali yuzani hisoblash
func calculate(s Shape) float32 {
return s.area()
}
func main() {
r := Rectangle{7, 4}
t := Triangle{8, 12}
rectangleArea := calculate(r)
fmt.Println("To'rtburchak yuzasi:", rectangleArea)
triangleArea := calculate(t)
fmt.Println("Uchburchak yuzasi:", triangleArea)
}
Natija:
To'rtburchak yuzasi: 28
Uchburchak yuzasi: 48
Bu yerda calculate() funksiyasi unga qaysi aniq struktura (Rectangle yoki Triangle) kelishidan qat'i nazar, faqat area() metodi borligiga ishonadi va uni to'g'ri hisoblayveradi.
Struktura interfeysni to'liq qanoatlantirishi uchun undagi barcha metodlarni o'zida yozishi shart. Agar bittasi bo'lsa ham qolib ketsa, kompilyator xatolik beradi:
package main
import "fmt"
type Shape interface {
area() float32
perimeter() float32 // 2 ta metod talab qilinmoqda
}
type Rectangle struct {
length, breadth float32
}
// Faqat area() yozildi, perimeter() esa yo'q!
func (r Rectangle) area() float32 {
return r.length * r.breadth
}
func calculate(s Shape) {
fmt.Println("Yuzasi:", s.area())
}
func main() {
r := Rectangle{7, 4}
calculate(r) // XATOLIK!
}
Kompilyator xatosi:
cannot use r (type Rectangle) as type Shape in argument to calculate:
Rectangle does not implement Shape (missing perimeter method)
Bu xatolik Rectangle da perimeter() metodi yo'qligini aniq ko'rsatib turibdi.