在golang中定义接口时如何思考?

时间:2017-01-13 21:45:02

标签: inheritance go polymorphism

我注意到在过去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}

1 个答案:

答案 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)否则你会失去一些语言的潜力。