go 面向对象编程

面向对象

go 语言面向对象与C++,Java等语言不同之处, 在与go不支持继承。Go 语言只支持聚合和嵌入, 通过一个简单的例子来了解一下go中的聚合和嵌入

type ColoredPoint struct {
            color.Color // 匿名字段(嵌入)
            x, y int    // 具名字段 (聚合)
} 

在ColoredPoint结构体中, color.Color引入其他包的类型,x, y 都属于整型,他们都属于结构体的字段。由于color.Color字段是匿名的(因为他没有变量名), 所以称之为匿名字段,即嵌入字段。而x, y是有具名的聚合字段。其字段可以通过point.Color, point.x, point.y直接访问, 注意的是,如果是匿名字段的话, 可以直接使用其名字最后一部分。
Go没有继承的概念,所以就没有所谓的虚函数。但是go支持类型安全的鸭子类型,而且嵌入也可以实现类似继承的功能。这个都是后话了。

自定义类型

创建语法

type typeName typeSpecification

typeName可以使 Go 语言中任意合法的标识符, 而typeSpecification可以是任何内置的类型(int string float struct chan)可以是接口, 还可以是方法签名。
看一下例子

type newInt int
type stringMap map[string]string
type people struct{}

var i newInt => var i int   //似乎和C语言的type没啥区别

添加方法

方法是作用在自定义类型的值上的一类特殊函数, 通常自定义类型的值会被传递给函数。该值可以以指针或者只的形式传递,这取决于方法如何定义。定义方法的语法几乎等同于定义函数, 出了需要在func关键字和方法名之间必须写上接受者(写于括号中) 之外。
我们可以为任何自定义的类型添加一个或者多个方法。一个方法的接受者总是该类型的值, 或者该类型值的指针。
对于任何一个给定的类型, 每个方法名都是必须唯一的。
举个列子

type People struct {
    age int
    name string
}
func (this *People) printAge() {
    fmt.Println(this.age)
}

func(this *People) printName() {
    fmt.Println(this.name)
}

func main() {
    jack := People{name:"jack", age:12}
    jack.printAge()
    jack.printName()
}

输出

12
jack

首先定义People结构体类型, 然后给两个方法作为接受者, 这时候便是给Peopel添加个两个方法。

重写方法

来举个例子来说明

type Fruit struct {
        price int
        quantity int
}

func (fruit *Fruit) Cost() int {
    return fruit.price * fruit.quantity
}

type SpecialFruit struct {
        Fruit  // 匿名字段 (嵌入)
        markup int  // 具名字段 (聚合)
}

// 重写
func (specialFruit *SpecialFruit) Cost() int {
    return specialFruit.Fruit.Cost()  * specialFruit.markup
}

func main() {
    res := SpecialFruit{Fruit{price:12, quantity:12}, 10}
    fmt.Println(res.Cost())
}

1440

如果你没有重写的话, 可以试试看, 输出结果就是144。 直接调用的 嵌入的Fruit的Cost方法

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 4

没有 get 到重写方法的含义. 我理解的 SpecialFruit 就是一个独立的 struct, 它的 cost 方法, 就是它的方法, 只是重名了而已, 如果不给它定义 cost 方法, 就没法调用吧

5年前 评论
JaguarJack

@rachel Fruit 是嵌入的。specialFruit.Fruit.Cost() 还是可以调用的

5年前 评论

@JaguarJack 哦, 懂了, 因为 specialFruit 结构中有一个字段类型是 Fruit, 确实有点继承的意思, 谢谢啦 :star2:

5年前 评论
JaguarJack

@rachel 你可以用继承来理解

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!