对我来讲,最吸引个人不是Go拥有的特征,而是那些被故意遗漏的特征。 —— txxxxdgolang
为何你要创造一种从理论上来讲,并不使人兴奋的语言?
由于它很是有用。 —— Rob Pikejson
要探讨Go语言中的对象,咱们先搞清楚一个问题:数组
从语法上来讲,函数
对象是一种抽象的数据类型,拥有状态(数据)和行为(代码)。 —— Steve Franciaui
在Go语言中,咱们这样声明一个类型:code
type Rect struct { width int height int }
func (r *Rect) Area() int { return r.width * r.height }
func main() { r := Rect{width: 10, height: 5} fmt.Println("area: ", r.Area()) }
咱们不光能够声明结构体类型,咱们能够声明任何类型。好比一个切片:对象
type Rects []*Rect
func (rs Rects) Area() int { var a int for _, r := range rs { a += r.Area() } return a }
func main() { r := &Rect{width: 10, height: 5} x := &Rect{width: 7, height: 10} rs := Rects{r, x} fmt.Println("r's area: ", r.Area()) fmt.Println("x's area: ", x.Area()) fmt.Println("total area: ", rs.Area()) }
https://play.golang.org/p/G1OWXPGvc3继承
咱们甚至能够声明一个函数类型接口
type Foo func() int
func (f Foo) Add(x int) int { return f() + x }
func main() { var x Foo x = func() int { return 1 } fmt.Println(x()) fmt.Println(x.Add(3)) }
https://play.golang.org/p/YGrdCG3SlIip
经过上边的例子,这样看来,其实
那么咱们来看看
若是一种语言包含对象的基本功能:标识、属性和特性,则一般认为它是基于对象的。
若是一种语言是基于对象的,而且具备多态性和继承性,那么它被认为是面向对象的。 —— Wikipedia
第一条,咱们在上边的例子看到了,go中的type declaration其实知足了Go语言是基于对象的。那么,
咱们来看看关于第二条,继承性和多态性
继承把“知识”向下传递,组合把“知识”向上拉升 —— Steve Francia
type Person struct { Name string Address } type Address struct { Number string Street string City string State string Zip string }
func (a *Address) String() string { return a.Number + " " + a.Street + "\n" + a.City + ", " + a.State + " " + a.Zip + "\n" }
func main() { p := Person{ Name: "Steve", Address: Address{ Number: "13", Street: "Main", City: "Gotham", State: "NY", Zip: "01313", }, } }
func main() { p := Person{ Name: "Steve", Address: Address{ Number: "13", Street: "Main", City: "Gotham", State: "NY", Zip: "01313", }, } fmt.Println(p.String()) }
https://play.golang.org/p/9beVY9jNlW
func (a *Address) String() string { return a.Number + " " + a.Street + "\n" + a.City + ", " + a.State + " " + a.Zip + "\n" } func (p *Person) String() string { return p.Name + "\n" + p.Address.String() }
外部结构的方法和内部结构的方法都是可见的
func main() { p := Person{ Name: "Steve", Address: Address{ Number: "13", Street: "Main", City: "Gotham", State: "NY", Zip: "01313", }, } fmt.Println(p.String()) fmt.Println(p.Address.String()) }
https://play.golang.org/p/Aui0nGa5Xi
func isValidAddress(a Address) bool { return a.Street != "" } func main() { p := Person{ Name: "Steve", Address: Address{ Number: "13", Street: "Main", City: "Gotham", State: "NY", Zip: "01313", }, } // 这里不能用 p (Person类型) 做为 Address类型的IsValidAddress参数 // cannot use p (type Person) as type Address in argument to isValidAddress fmt.Println(isValidAddress(p)) fmt.Println(isValidAddress(p.Address)) }
https://play.golang.org/p/KYjXZxNBcQ
为不一样类型的实体提供单一接口
一般经过泛型、重载和/或子类型实现
Go语言采用了鸭式辩型,和JavaScript相似。鸭式辩型的思想是,只要一个动物走起路来像鸭子,叫起来像鸭子,那么就认为它是一只鸭子。
也就是说,只要一个对象提供了和某个接口一样(在Go中就是相同签名)的方法,那么这个对象就能够当作这个接口来用。并不须要像Java中同样显式的实现(implements)这个接口。
type Shaper interface{ Area() int }
func Describe(s Shaper) { fmt.Println("Area is: ", s.Area()) }
func main() { r := &Rect{width: 10, height: 5} x := &Rect{width: 7, height: 10} rs := &Rects{r, x} Describe(r) Describe(x) Describe(rs) }
https://play.golang.org/p/WL77LihUwi
“若是你能够从新作一次Java,你会改变什么?”
“我会去掉类class,” 他回答道。
在笑声消失后,他解释道,真正的问题不是类class自己,而是“实现”的继承(类之间extends的关系)。接口的继承(implements的关系)是更可取的方式。
只要有可能,你就应该尽量避免“实现”的继承。
—— James Gosling(Java之父)
这也就是上边所说的鸭式辩型
type Reader interface { Read(p []byte) (n int, err error) }
type Writer interface { Write(p []byte) (n int, err error) }
func MarshalGzippedJSON(r io.Reader, v interface{}) error { raw, err := gzip.NewReader(r) if err != nil { return err } return json.NewDecoder(raw).Decode(&v) }
func main() { f, err := os.Open("myfile.json.gz") if err != nil { log.Fatalln(err) } defer f.Close() m := make(map[string]interface{}) MarshalGzippedJSON(f, &m) }
func main() { resp, err := http.Get("...") if err != nil { log.Fatalln(err) } defer resp.Body.Close() out, err := os.Create("filename.ext") if err != nil { log.Fatalln(err) } defer out.Close() io.Copy(out, resp.Body) // out io.Writer, resp.Body io.Reader }
简单比复杂更难:你必须努力使你的思惟清晰,使之简单。但最终仍是值得的,由于一旦你到了那里,你就能够移山。 —— Steve Jobs