Golang Notları - Türetme - Inheritance

yazılım
go

#1

Golangde turetme C++, Java gibi dillerine gore biraz farkli ele alinmis. Bilinen manada bir class yok, public-private-protected isim alanlari veya anahtar sozcukleri yok. Konu biraz daha composition (sahip olma) temelli ve dilin tasariminda da hissedilen basitlik ilkesine sadik kalinmis.

Ornegin;

Sekil adinda bir taban yapisi olusturalim ve bu yapida sadece turetilen nesnelerin adlari tutulsun. Kare ve Daire yapilari da bahsettigimiz gibi Sekil yapisina sahip olsun (composition). Normalde C++ veya Java terminolojisinde turetme kelimesini kullanirdik ama golang de isler daha farkli. Asagidaki kod ornegini inceleyelim;

package main

import (
	"fmt"
	"math"
)

type Sekil struct {
	isim string
}

type Kare struct {
	Sekil
	kenar float64
}

type Daire struct {
	Sekil
	yaricap float64
}

func main() {

	c := Daire{
		Sekil:  Sekil{"Daire"},
		yaricap: 5,
	}

	s := Kare{
		Sekil: Sekil{"Kare"},
		kenar:  5,
	}

	fmt.Printf("isim:%s alan:%f\n", c.Sekil.isim, math.Pi*c.yaricap*c.yaricap)
	fmt.Printf("isim:%s alan:%f\n", s.Sekil.isim, s.kenar*s.kenar)
}

Goruldugu uzere direkt sahip olma ile bir iliskilendirme mevcut kisacasi C++ ve Java notasyonundan farkli bir yaklasim mevcut.

Bir diger onemli mevzu ise isimlendirme. Yapilarin (Struct) isimleri dikkat ederseniz buyuk harfle baslamis. Bu her ne kadar diger dillerde cok da ozel manaya gelmese de Go’ da oldukca ozel bir manasi var. Buyuk harfle baslar ise bu yapilarin package isim alani (isim alanlarini daha sonra baska bir yaziyla yazariz insallah :slight_smile: ) disina hizmet verip vermemesini belirliyor. Bunu da nacizane encapslation olarak alabilirsiniz. Isimler eger Buyuk harfle basladiysa disardaki isim alanlarina da hizmet verecek manasina geliyor, tam tersi kucuk harfle basliyorsa sadece ayni isim alanina hizmet veriyor.

Peki polimorphism (calisma zamani cok cesitliligi) nasil saglanmis ? Bunu da interface’ ler ile cozmusler. Java veya C++ dakine benzer ama nuans farkliliklari var. Go daki interfaceler aslinda bir nevi implemente edilmesi gereken method imzalarinin bir kumesi niteliginde. Herhangi bir yapi (struct) bu metodlari implemente ederse direkt olarak o turun bir ornegi olarak kabul gorur. Koda bakalim abi cok yazdik :slight_smile:

package main

import (
	"fmt"
	"math"
)

type Sekil interface {
	alan() float64
}

type Kare struct {
	kenar float64
}

type Daire struct {
	yaricap float64
}

func (s Kare) alan() float64 {
	return s.kenar * s.kenar
}

func (c Daire) alan() float64 {
	return math.Pi * c.yaricap * c.yaricap
}

func getalan(s Sekil) float64 {

	fmt.Printf("Tur: %T  ", s)
	return s.alan()
}

func main() {

	c := Daire{5}
	s := Kare{4}

	fmt.Printf("%v\n", getalan(c))
	fmt.Printf("%v\n", getalan(s))

}

Ornekte goruldugu uzere Kare ve Daire yapilari “alan() float64” imzali fonksiyonunu implemente ettikleri ikisi de ayni zamanda Sekil sinifinin birer ornegi. Bu sayede getalan(s Sekil) fonksiyonuna parametre olarak Daire veya Kare cinsinden nesneler gonderebiliyorum. Zaten icerde %T ile turunu yazdirdigimizda size gercek turunu soyleyecektir. Kisacasi ustteki program calistirildiginda alttaki ciktiyi verecektir :

iyasar$ go run main.go
Tur: main.Daire 78.53981633974483
Tur: main.Kare 16

Bu sayede RTTI (Run Time Type Identification) yani calisma zamani cok cesitliligi de saglanmis oldu. Bu arada dikkatinizi cekmistir :

func (s Kare) alan() float64

alan fonksiyonu imzasinda ‘alan’ isminden once gelen (s Kare) aslinda Go dili terminolojisinde ‘receiver’ yani o tur uzerinde islem yapan bir fonksiyon oldugunu belirtir. Kisacasi o fonksiyona anladigimiz mana da ‘this’ gostericisi gecilmis olur. Boylelikle bir nevi uye fonksiyonumuzu (class member function) da Go dilinde elde etmis oluruz :slight_smile:

Firsat buldukca Go dilinde ogrendiklerimi yazmaya devam edecegim.