Gönderen Az Üstel More
C ++ ve Java tür hiyerarşileri ve türlerin sınıflandırması ile ilgiliyse, Go kompozisyon ile ilgilidir.
Gönderen Az Üstel More
C ++ ve Java tür hiyerarşileri ve türlerin sınıflandırması ile ilgiliyse, Go kompozisyon ile ilgilidir.
Yanıtlar:
O, şu sırayla bir şey kullanacağınız anlamına gelir:
class A : public B {};
Java veya C ++ gibi bir şeyde, Go'da (buna eşdeğer bir şey) kullanırsınız:
class A {
B b;
};
Evet, bu kalıtım benzeri özellikler sağlar. Yukarıdaki örneği biraz genişletelim:
struct B {
int foo() {}
};
struct A {
B b;
};
A a;
a.foo(); // not allowed in C++ or Java, but allowed in Go.
Ancak bunu yapmak için, C ++ veya Java'da izin verilmeyen bir sözdizimi kullanırsınız - katıştırılmış nesneyi kendi adı olmadan bırakırsınız, bu yüzden daha çok şuna benzer:
struct A {
B;
};
Bu soru / sorun benzer türüdür bu bir .
Go'da gerçekten OOP'niz yok.
Bir nesneyi "uzmanlaştırmak" istiyorsanız, bunu bir kompozisyon olan gömme ile yaparsınız, ancak bazı güzellikler onu kalıtımla kısmen benzer hale getirir . Bunu şöyle yapın:
type ConnexionMysql struct {
*sql.DB
}
Bu örnekte, ConnexionMysql * sql.DB'nin bir uzmanlık alanıdır ve ConnexionMysql üzerinde * sql.DB'de tanımlanan işlevleri çağırabilirsiniz:
type BaseMysql struct {
user string
password string
database string
}
func (store *BaseMysql) DB() (ConnexionMysql, error) {
db, err := sql.Open("mymysql", store.database+"/"+store.user+"/"+store.password)
return ConnexionMysql{db}, err
}
func (con ConnexionMysql) EtatBraldun(idBraldun uint) (*EtatBraldun, error) {
row := con.QueryRow("select pv, pvmax, pa, tour, dla, faim from compte where id=?", idBraldun)
// stuff
return nil, err
}
// somewhere else:
con, err := ms.bd.DB()
defer con.Close()
// ...
somethings, err = con.EtatBraldun(id)
Yani ilk bakışta bu kompozisyonun normal taksonominizi yapmanın bir aracı olduğunu düşünebilirsiniz.
Fakat
* sql.DB'de tanımlanan bir işlev * sql.DB'de tanımlanan diğer işlevleri çağırırsa, ConnexionMysql'de yeniden tanımlanmış işlevleri olsalar bile çağırmaz.
Klasik miras ile genellikle böyle bir şey yaparsınız:
func (db *sql.DB) doComplexThing() {
db.doSimpleThing()
db.doAnotherSimpleThing()
}
func (db *sql.DB) doSimpleThing() {
// standard implementation, that we expect to override
}
Yani, doComplexThing
süper sınıfta uzmanlık çağrıları yapan bir organizasyon olarak tanımlayabilirsiniz .
Ancak Go'da bu özel işlev değil, "üst sınıf" işlevi olarak adlandırılır.
Bu nedenle, * sql.DB'de tanımlanmış ancak ConnexionMySQL'de (veya diğer uzmanlıklarda) yeniden tanımlanmış bazı işlevleri çağırmak isteyen bir algoritmaya sahip olmak istiyorsanız, bu algoritmayı * sql.DB'nin bir işlevi olarak tanımlayamazsınız, ancak başka bir yerde tanımlamanız gerekir ve bu işlev yalnızca sağlanan uzmanlığa yapılan çağrıları oluşturur.
Arayüzleri kullanarak bunu şöyle yapabilirsiniz:
type interface SimpleThingDoer {
doSimpleThing()
doAnotherSimpleThing()
}
func doComplexThing(db SimpleThingDoer) {
db.doSimpleThing()
db.doAnotherSimpleThing()
}
func (db *sql.DB) doSimpleThing() {
// standard implementation, that we expect to override
}
func (db ConnexionMySQL) doSimpleThing() {
// other implemenation
}
Bu, sınıf hiyerarşilerinin klasik geçersiz kılmasından oldukça farklıdır.
Özellikle, doğrudan bir fonksiyonun ikincisinden miras kalan üçüncü bir seviyeye sahip olamayacağınız açıktır.
Uygulamada, çoğunlukla (dikey) arayüzleri kullanmayı sona erdirirsiniz ve uygulamanın, uygulamanın bu üst sınıflarını "üst sınıf" ına sahip olmak yerine, verilen bir uygulamadaki çağrıları oluşturmasına izin verirsiniz.
Deneyimlerime göre, bu, bir seviyeden daha derin hiyerarşilerin pratik yokluğuna yol açar.
Çoğu zaman, diğer dillerde, A kavramının B kavramının bir uzmanlığı olduğunu gördüğünüzde, B'nin bir alt sınıfı olarak bir B sınıfı ve A sınıfı oluşturarak bu gerçeği yeniden tanımlamak için refleksiniz vardır. verilerinizin etrafında programlayın, kodunuzdaki nesnelerin sınıflandırmasını yeniden üretmek için zaman harcarsınız, bu gerçekliktir.
Go'da genel bir algoritma tanımlayamaz ve onu özelleştiremezsiniz. Genel bir algoritma tanımlamalı ve genel olduğundan ve sağlanan arayüz uygulamalarıyla çalıştığından emin olmalısınız.
Kodlayıcıların, mantığı nihayet tüm seviyeleri ima eden bir algoritmayı barındırmak için karmaşık hackler yaptığı bazı hiyerarşi ağaçlarının artan karmaşıklığından dehşete düştükten sonra, daha basit Go mantığından memnun olduğumu söyleyebilirim, sadece uygulama modelinizin kavramlarını yeniden tanımlamak yerine düşünmeniz gerekir.