我注意到在过去10年左右的时间里放弃我在Java和PHP中使用的OOP样式编程是多么困难。几个星期以来我一直在给golang一个去(双关语),但我试图在golang的继承原则上对组合感到自然。
我如何定义一个有用的接口来确保所有这些结构都可以实现它?我试图提出一个有用的例子,不涉及狗,人类或奇怪的车辆构造......
package main
type Store struct {
name string
phone string
}
type HardwareStore struct{ Store }
type FoodStore struct{ Store }
type OnlineStore struct {
Store
url string
}
我认为这可能是因为我的思考基于他们的状态/数据,而不是他们的行为,我有点挣扎。
没有界面的明显的第一选择可能就是这个(简化),当然会失败:
s := Store{}
h := HardwareStore{}
f := FoodStore{}
o := OnlineStore{}
stores := []Store{s, h, f, o}
答案 0 :(得分:2)
我认为以下就是你所追求的。抱歉丑陋的名字,但我必须让他们脱颖而出才能说明问题。请记住,go中没有虚函数,即使下面的例子模拟了一个。
package main
import "fmt"
type StoreInterface interface {
getName() string
setName(string)
getPhone() string
setPhone(string)
}
type Store struct {
name string
phone string
}
func (store *Store) getName() string {
return store.name;
}
func (store *Store) setName(newName string){
store.name = newName;
}
func (store *Store) getPhone() string {
return store.phone;
}
func (store *Store) setPhone(newPhone string){
store.phone = newPhone;
}
type HardwareStore struct{ Store }
type FoodStore struct{ Store }
type OnlineStore struct {
Store
url string
}
func (os *OnlineStore) getName() string{
return fmt.Sprintf("%v(%v)", os.name, os.url)
}
func main() {
s := Store{name:"s", phone:"111"}
h := HardwareStore{Store{name:"h", phone:"222"}}
f := FoodStore{Store{name:"f", phone:"333"}}
o := OnlineStore{Store:Store{name:"o", phone:"444"}, url:"http://test.com"}
fmt.Println ("Printout 1")
stores := []*Store{&s, &h.Store, &f.Store, &o.Store}
for _, s := range stores {
fmt.Printf("\t%v: %v\n", s.name, s.phone);
}
fmt.Println ("Printout 2")
stores2 := []StoreInterface{&s, &h, &f, &o}
for _, s := range stores2 {
fmt.Printf("\t%v: %v\n", s.getName(), s.getPhone());
}
}
但是,毫无疑问,您需要将您的思维方式从继承更改为函数,数据结构和行为。很难打破旧习惯(我也来自多年的OOP)。但是当你在罗马时,你应该像罗马人那样思考:o)否则你会失去一些语言的潜力。