官方关于golang的继承和重载的FAQ 原文部分来自:https://segmentfault.com/a/1190000022429780
关于类型继承 面向对象的编程,至少在最著名的语言中,涉及对类型之间关系的过多讨论,这些关系通常可以自动派生。Go 采取了不同的方法。
与其要求程序员提前声明两种类型是相关的,在 Go 中,类型会自动满足任何指定其方法子集的接口。除了减少簿记之外,这种方法还有真正的优势。类型可以同时满足多个接口,没有传统多重继承的复杂性。接口可以是非常轻量级的——具有一个甚至零个方法的接口可以表达一个有用的概念。如果出现新想法或用于测试,可以事后添加接口——无需注释原始类型。因为类型和接口之间没有明确的关系,所以没有要管理或讨论的类型层次结构。
可以使用这些想法来构建类似于类型安全的 Unix 管道的东西。例如,了解如何fmt.Fprintf 为任何输出启用格式化打印,而不仅仅是文件,或者bufio包如何与 文件 I/O 完全分离,或者image包如何生成压缩图像文件。所有这些想法都源于io.Writer表示单个方法 ( Write)的单个接口( )。而这只是皮毛。Go 的接口对程序的结构有着深远的影响。
这需要一些时间来适应,但这种隐式的类型依赖是 Go 最高效的事情之一。
–faq: https://golang.org/doc/faq#inheritance
关于重载的定义 如果不需要进行类型匹配,则方法分派会得到简化。使用其他语言的经验告诉我们,拥有多种名称相同但签名不同的方法有时很有用,但在实践中也可能会令人困惑和脆弱。仅按名称匹配并要求类型的一致性是 Go 类型系统中一个主要的简化决定。
关于运算符重载,它似乎更方便而不是绝对要求。同样,没有它,事情会更简单。
– faq:https://golang.org/doc/faq#overloading
从一个案例引入 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 type ShapeInterface interface { Area() float64 GetName() string PrintArea() } type Shape struct { name string } func (s *Shape) GetName() string { return s.name } func (s *Shape) Area() float64 { return 0.0 } func (s *Shape) PrintArea() { fmt.Printf("%s : Area %v\r\n", s.GetName(), s.Area()) } // Rectangle 矩形求面积 type Rectangle struct { Shape w, h float64 } func (r *Rectangle) Area() float64 { return r.w * r.h } // Circle 圆形 : 重新定义 Area 和PrintArea 方法 type Circle struct { Shape r float64 } func (c *Circle) Area() float64 { return c.r * c.r * math.Pi } func (c *Circle) PrintArea() { fmt.Printf("%s : Area %v\r\n", c.GetName(), c.Area()) } func main() { s := Shape{name: "Shape"} c := Circle{Shape: Shape{name: "Circle"}, r: 10} r := Rectangle{Shape: Shape{name: "Rectangle"}, w: 5, h: 4} listshape := []ShapeInterface{&s, &c, &r} for _, si := range listshape { si.PrintArea() //!! 猜猜哪个Area()方法会被调用 !! } } out: Shape : Area 0 Circle : Area 314.1592653589793 Rectangle : Area 0 // 为啥这里没有调用 5 * 4 原因分析:Rectangle通过组合Shape获得的PrintArea()方法并没有去调用Rectangle实现的Area()方法,而是去调用了Shape的Area()方法。Circle是因为自己重写了PrintArea()所以在方法里调用到了自身的Area()。
...