Interface'ler ile Polimorfizm
Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 41 / 107.
Polimorfizm, farklı türlerin ortak bir arayüz aracılığıyla tek tip olarak ele alınmasını sağlar. Go'da bu, kalıtım veya sınıf hiyerarşileri olmadan tamamen arayüzler aracılığıyla gerçekleştirilir.
Bir işlev, bir arayüz türünü parametre olarak kabul ettiğinde, bu arayüzü uygulayan herhangi bir somut tür işleve aktarılabilir. İşlevin belirli türü bilmesine gerek yoktur. Yalnızca arayüz tarafından tanımlanan davranışla ilgilenir:
type Speaker interface {
Speak() string
}
type Dog struct{ Name string }
func (d Dog) Speak() string { return "Woof!" }
type Cat struct{ Name string }
func (c Cat) Speak() string { return "Meow!" }
func MakeSound(s Speaker) {
fmt.Println(s.Speak())
}
Artık MakeSound, Speak() yöntemine sahip herhangi bir türle çalışır:
func main() {
dog := Dog{Name: "Rex"}
cat := Cat{Name: "Whiskers"}
MakeSound(dog) // Hav!
MakeSound(cat) // Miyav!
}
Aynı işlev çağrısı, geçirilen gerçek türe bağlı olarak farklı davranışlar üretir. Bu, polimorfizmin işleyiş hâlidir. MakeSound işlevi bir kez yazılır, ancak Speaker arayüzünü sağladıkları sürece sınırsız sayıda türle çalışır.
Bu yaklaşım kodunuzu esnek ve genişletilebilir tutar. Konuşan yeni bir tür eklemek, mevcut işlevlerde hiçbir değişiklik gerektirmez; yalnızca arayüzü uygulayın ve otomatik olarak çalışır.
Görev
KolayPolimorfizmi uygulamalı olarak gösteren bir araç açıklama sistemi oluşturalım. Ortak bir davranışı bir arayüz aracılığıyla paylaşan farklı araç türleri oluşturacak, ardından herhangi bir araçla çalışabilen tek bir işlev yazacaksın.
Kodunu iki dosyaya ayıracaksın:
vehicles.go:Describermetodunu gerektiren birDescribe() stringarayüzü tanımla. Ardından bu arayüzü kendi yöntemleriyle uygulayan üç araç türü oluştur:CarveBrandalanlarına sahipModel.Describe()metoduCar: [Brand] [Model]değerini döndürürMotorcycleveBrand(int) alanlarına sahipEngineCC.Describe()metoduMotorcycle: [Brand] [EngineCC]ccdeğerini döndürürBicyclealanına sahipType(örneğin "Mountain" veya "Road").Describe()metoduBicycle: [Type]değerini döndürür
main.go: Herhangi birPrintDescriptionkabul eden veDescriberçağrısının sonucunu yazdıranDescribe()adlı bir işlev oluştur. Araç bilgilerini girdiden oku, her araç türünden bir tane oluştur ve aynı işlevin üç farklı türle de çalıştığını göstermek için her biriniPrintDescriptionişlevine aktar.
Aşağıdaki girdiler sağlanacaktır:
- 1. satır: Car markası
- 2. satır: Car modeli
- 3. satır: Motorcycle markası
- 4. satır: Motorcycle motor CC değeri (tam sayı)
- 5. satır: Bicycle türü
Örneğin Toyota, Camry, Honda, 600 ve Mountain verildiğinde çıktın şu şekilde olmalıdır:
Car: Toyota Camry
Motorcycle: Honda 600cc
Bicycle: MountainPrintDescription işlevinin bir Car, Motorcycle veya Bicycle alıp almadığını bilmesine gerek olmadığına dikkat et. İşlev yalnızca Describe() çağrısını yapar ve her tür kendi benzersiz çıktısıyla yanıt verir. Polimorfizm budur: tek işlev, birden fazla davranış.
Kendin dene
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
// TODO: Herhangi bir Describer kabul eden PrintDescription adında bir fonksiyon oluştur
// ve Describe() çağrısının sonucunu yazdırır
func main() {
reader := bufio.NewReader(os.Stdin)
// Araba detaylarını oku
carBrand, _ := reader.ReadString('\n')
carBrand = strings.TrimSpace(carBrand)
carModel, _ := reader.ReadString('\n')
carModel = strings.TrimSpace(carModel)
// Motosiklet detaylarını oku
motoBrand, _ := reader.ReadString('\n')
motoBrand = strings.TrimSpace(motoBrand)
motoEngineStr, _ := reader.ReadString('\n')
motoEngineStr = strings.TrimSpace(motoEngineStr)
motoEngine, _ := strconv.Atoi(motoEngineStr)
// Bisiklet detaylarını oku
bicycleType, _ := reader.ReadString('\n')
bicycleType = strings.TrimSpace(bicycleType)
// TODO: Giriş değerlerini kullanarak bir Car, Motorcycle ve Bicycle oluştur
// TODO: Polimorfizmi göstermek için her araç için PrintDescription çağır
fmt.Println("TODO: Print vehicle descriptions")
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Go OOP Temelleri
Harici DosyalarGo Çalışma Alanı ve ModüllerPaketler ve İçe AktarmalarDışa Aktarılan ve Aktarılmayan İsimlerGo'da OOP'ye GirişSınıf Olarak Struct'larStruct'larda Metot TanımlamaPointer ve Değer AlıcılarStruct BaşlatmaYapıcı FonksiyonlarÖzet - Basit Hesap Makinesi4Arayüzler
Arayüzlere GirişÖrtük UygulamaSözleşme Olarak ArayüzBoş Arayüz (any)Tür OnaylamaTür SeçimiArayüz BileşimiStringer ve Error ArayüzleriÖzet - Şekil Hesaplayıcı7Kapsülleme
Dışa Aktarılan ve Aktarılmayan AlanlarPaket Seviyesinde KapsüllemeGetter ve Setter MetotlarıGo'da Bilgi GizlemeÖzet - Öğrenci Kayıtları10Generics (Go 1.18+)
Generics'e GirişTür ParametreleriTür KısıtlamalarıGeneric Struct'larGeneric Metotlar İçin Geçici ÇözümÖzet - Generic Koleksiyon13Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıAbstract Factory KalıbıObserver KalıbıStrategy Kalıbı2Türler ve Struct'lar: Derinlemesine İnceleme
Temel ve Bileşik TürlerÖzel Tür TanımlamalarıStruct EtiketleriAnonim Struct'larİç İçe Geçmiş Struct'larSıfır Değerler ve VarsayılanlarÖzet - Rehber5Kalıtım Yerine Kompozisyon
Go'da Neden Kalıtım YokStruct Gömme TemelleriMetot YükseltmeBirden Fazla Struct GömmeGömme vs AgregasyonGömülü Metotları GölgelemeÖzet - Çalışan Hiyerarşisi8Hata Yönetimi ve OOP
error ArayüzüÖzel Hata TürleriHata Sarmalama (fmt.Errorf)Sentinel Hatalarerrors.Is() ve errors.As()Panic, Defer ve RecoverÖzet - Dosya Ayrıştırıcı3İşaretçiler ve Bellek
Go'da İşaretçi TemelleriStruct İşaretçileriDeğer ile Geçme ve Referans ile Geçmenew() FonksiyonuGo'da Garbage CollectionÖzet - Linked List Oluşturucu6Go'da Polimorfizm
Interface'ler ile PolimorfizmGo'da Duck TypingInterface Karşılama KurallarıPolimorfik KoleksiyonlarDependency InjectionÖzet - Payment Processor9Eşzamanlılık ve OOP
Goroutine TemelleriKanallar ve İletişimTamponlu ve Tamponsuz KanallarSelect İfadesisync.Mutex ve sync.RWMutexsync.WaitGroupThread-Safe Struct TasarımıÖzet - Worker PoolKendi başına pratik yap: Online Go derleyicisi