首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在golang中定义接口时如何思考?

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

Stack Overflow用户
提问于 2017-01-14 05:45:02
回答 1查看 625关注 0票数 4

我已经注意到,放弃过去10年左右在Java和PHP中使用的OOP风格编程是多么困难。从几个星期开始,我就开始尝试golang (双关语),但我试图围绕golang的组合而不是继承原则感到自然。

我该如何定义一个有用的接口来确保所有这些结构都能满足它呢?我试着想出一个有用的例子,既不涉及狗,也不涉及人类或奇怪的车辆构造……

代码语言:javascript
复制
package main

type Store struct {
  name  string
  phone string
}

type HardwareStore struct{ Store }

type FoodStore struct{ Store }

type OnlineStore struct {
  Store
  url string
}

我想这可能是因为我的想法是基于他们的状态/数据,而不是他们的行为,我有点挣扎。

在没有接口的情况下,最明显的首选可能是这样(简化),这当然会失败:

代码语言:javascript
复制
s := Store{}
h := HardwareStore{}
f := FoodStore{}
o := OnlineStore{}

stores := []Store{s, h, f, o}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-14 07:27:08

我想下面就是你想要的。很抱歉给你起难看的名字,但我必须让它们脱颖而出才能说明问题。请记住,go中没有虚拟函数,即使下面的示例模拟了一个虚拟函数。

代码语言:javascript
复制
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),否则你就会错过这种语言的一些潜力。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41643909

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档