Menu
Coddy logo textTech

Go'da Neden Kalıtım Yok

Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 34 / 107.

Java ve C++ gibi geleneksel nesne yönelimli diller, türler arasında kod paylaşmak için kalıtımı kullanır. Bir alt sınıf, bir üst sınıfı genişleterek tüm alanlarını ve yöntemlerini devralır. Go bu özelliği kasıtlı olarak içermez.

Kalıtım, türler arasında sıkı bağımlılık oluşturur. Bir üst sınıf değiştiğinde, tüm alt sınıflar etkilenir.

Derin kalıtım hiyerarşilerini anlamak ve sürdürmek zorlaşır. "kırılgan temel sınıf sorunu", bir temel sınıfta yapılan değişikliklerin türetilmiş sınıfları beklenmedik bir şekilde bozması durumunda ortaya çıkar.

Go'nun tasarımcıları farklı bir yol seçti: kalıtım yerine bileşim. "Bir Dog is an Animal" demek yerine Go, "Bir Dog has Animal benzeri davranışlar" demenizi teşvik eder. Bu ince değişim, daha esnek ve bakımı daha kolay kodlar yazmanızı sağlar.

Go, daha önce öğrendiğiniz iki mekanizma aracılığıyla kodun yeniden kullanılmasını sağlar:

  • Interfaces uygulama ayrıntıları olmadan davranış sözleşmelerini tanımlar
  • Struct gömme, türlerin diğer türleri içermesine ve onların yöntemlerini yeniden kullanmasına olanak tanır

Bu karşılaştırmayı düşünün. Geleneksel OOP'de class Dog extends Animal yazabilirsiniz. Go'da Animal struct'ını Dog içine gömer ve paylaşılan arayüzleri uygularsınız. Sonuç, türler arasında daha gevşek bir bağ ile benzer işlevselliktir.

Bu bölüm, Go'nun kalıtımın avantajlarını dezavantajları olmadan nasıl elde ettiğini göstererek yapı gömmeyi derinlemesine inceler.

challenge icon

Görev

Kolay

Kalıtım yerine Go'nun bileşim yaklaşımını gösteren bir bildirim sistemi oluşturalım. Sınıf hiyerarşileri yerine arayüzler ve yapı gömme yoluyla davranışları paylaşan türler oluşturacaksınız.

Kodunuzu üç dosyaya ayıracaksınız:

  • notifier.go: Tek bir Notifier metoduna sahip bir Notify(message string) string arayüzü tanımlayın. Ayrıca, diğer türler tarafından gömülecek bir BaseNotifier alanına sahip Name yapısını oluşturun. BaseNotifier için, bildiricinin adını köşeli parantezler içinde mesajın önüne ekleyerek döndüren Format(message string) string adlı bir metot tanımlayın.
  • channels.go: BaseNotifier yapısını gömen ve Notifier arayüzünü uygulayan iki bildirim kanalı türü oluşturun:
    • Ek olarak EmailNotifier alanına sahip Address
    • Ek olarak SMSNotifier alanına sahip Phone
    Her türün Notify metodu, gömülü Format metodunu kullanmalı ve çıktıya kendine özgü kanal bilgilerini eklemelidir.
  • main.go: Herhangi bir SendAlert ve bir mesaj kabul eden, ardından Notifier çağrısının sonucunu döndüren Notify adlı bir işlev oluşturun. Bildirim ayrıntılarını girdiden okuyun, her iki bildirimci türünü de oluşturun ve arayüz üzerinden birbirlerinin yerine nasıl kullanılabileceklerini gösterin.

Aşağıdaki girdiler sağlanacaktır:

  • 1. satır: E-posta için bildirimci adı
  • 2. satır: E-posta adresi
  • 3. satır: SMS için bildirimci adı
  • 4. satır: Telefon numarası
  • 5. satır: Uyarı mesajı

Format üzerindeki BaseNotifier metodunuz şunu döndürmelidir:

[Name] message

Notify metotlarınız şunları döndürmelidir:

  • EmailNotifier: Email to [Address]: [formatted message]
  • SMSNotifier: SMS to [Phone]: [formatted message]

Örneğin, Alerts, user@mail.com, Urgent, 555-1234 ve Server down verildiğinde çıktınız şöyle olmalıdır:

Email to user@mail.com: [Alerts] Server down
SMS to 555-1234: [Urgent] Server down

Her iki bildirimci türünün de gömme yoluyla Format içindeki BaseNotifier metodunu yeniden kullandığına, ancak her birinin kendi Notify uygulamasını sağladığına dikkat edin. SendAlert işlevi, somut türü bilmeden herhangi bir Notifier ile çalışır. Bu, kalıtım yerine bileşimin uygulamadaki hâlidir.

Kendin dene

package main

import (
	"bufio"
	"fmt"
	"os"
)

// SendAlert herhangi bir Notifier ve bir mesaj kabul eder, Notify çağrısının sonucunu döndürür
// TODO: SendAlert fonksiyonunu uygula

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// E-posta bildirimcisinin adını oku
	scanner.Scan()
	emailName := scanner.Text()
	
	// E-posta adresini oku
	scanner.Scan()
	emailAddress := scanner.Text()
	
	// SMS bildirimcisinin adını oku
	scanner.Scan()
	smsName := scanner.Text()
	
	// Telefon numarasını oku
	scanner.Scan()
	phoneNumber := scanner.Text()
	
	// Uyarı mesajını oku
	scanner.Scan()
	alertMessage := scanner.Text()
	
	// TODO: emailName ve emailAddress ile bir EmailNotifier oluştur
	
	// TODO: smsName ve phoneNumber ile bir SMSNotifier oluştur
	
	// TODO: alertMessage'ı her iki bildirimci üzerinden göndermek için SendAlert kullan
	// ve sonuçları yazdır
	
	// Kullanılmayan değişken uyarılarını bastır (değişkenleri kullandığında bunları kaldır)
	_ = emailName
	_ = emailAddress
	_ = smsName
	_ = phoneNumber
	_ = alertMessage
}
quiz iconKendini test et

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

Kendi başına pratik yap: Online Go derleyicisi