Go 语言极速入门4 - 面向对象

一、自定义类

定义类:type 类名 struct

1.1、定义类

// user 类
type user struct {
    name       string
    email      string
    ext        int
    privileged bool
}

// admin 类
type admin struct {
    // 自定义类
    person user
    // 内置类型
    level string
}

1.2、实例化类

    // 1. 创建 user 变量,所有属性初始化为其零值
    var bill user
    fmt.Println(bill) // {  0 false}

    // 2. 创建 user 变量,并初始化属性值
    lisa := user{
        name:       "nana",
        email:      "117@qq.com",
        ext:        123,
        privileged: true,
    }
    fmt.Println(lisa) // {nana 117@qq.com 123 true}
    // 直接使用属性值,属性值的顺序要与 struct 中定义的一致
    lisa2 := user{"nana", "117@qq.com", 123, true}
    fmt.Println(lisa2) // {nana 117@qq.com 123 true}

    // 3. 含有自定义类型的 struct 进行初始化
    fred := admin{
        person: user{
            name:       "nana",
            email:      "117@qq.com",
            ext:        123,
            privileged: true,
        },
        level: "super",
    }
    fmt.Println("fred:", fred) // fred: {{nana 117@qq.com 123 true} super}

二、方法

  • 方法的定义方法实际上也是函数,只是在声明时,在关键字 func 和方法名之间增加了一个参数
  • 普通的函数定义 func 方法名(入参) 返回值
  • 自定义类型的方法定义 func (接收者) 方法名(入参) 返回值
  • 方法的值传递和指针传递
  • func (u user) notify() 拷贝一份 user
  • func (u *user) changeEmail(newEmail string) 传递指针(即地址),内部改变会影响外部
type user struct {
    name  string
    email string
}

// 普通的函数定义 "func 方法名(入参) 返回值"
// 自定义类型的函数定义 "func (接收者) 方法名(入参) 返回值"
// 值传递,拷贝一份 user
func (u user) notify() {
    fmt.Println("pass-by-value", u.name, u.email)
    u.email = "0@qq.com"
}

// 传递指针(即地址),内部改变会影响外部
func (u *user) changeEmail(newEmail string) {
    // 不需要 (*u).email
    u.email = newEmail
}

func main() {
    // 1. user类型的值可以用来调用使用值接收者声明的方法
    bill := user{"bill", "1@qq.com"}
    bill.notify() // {"bill", "1@qq.com"}
    fmt.Println("1", bill.email) // "1@qq.com"

    // 2. 指向 user 类型值的指针也可以用来调用使用值接收者声明的方法
    lisa := &user{"lisa", "2@qq.com"}
    // 等价于 (*lisa).notify()
    // 注意:把 lisa 指针指向的 user 对象复制了一份,"再强调一次,notify 操作的是一个副本,只不过这次操作的是从 lisa 指针指向的值的副本。"
    lisa.notify() // {"lisa", "2@qq.com"}
    fmt.Println("2", lisa.email) // "0@qq.com"(错)  2@qq.com(对)

    // 3.user 类型的值可以用来调用使用指针接收者声明的方法
    // 等价于 (&bill).changeEmail ("100@qq.com"),注意 changeEmail 接收的是一个指针
    bill.changeEmail("100@qq.com")
    fmt.Println("3", bill.email) // "100@qq.com"

    // 4.指向 user 类型值的指针可以用来调用使用指针接收者声明的方法
    lisa.changeEmail("200@qq.com")
    fmt.Println("4", lisa.email) // "200@qq.com"
}

注意:着重注意2,“再强调一次,notify 操作的是一个副本,只不过这次操作的是从 lisa 指针指向的值的副本。”

三、嵌入类型

  • Go 语言允许用户扩展或者修改已有类型的行为。这个功能是通过嵌入类型 type embedding 完成的。嵌入类型是将已有的类型直接声明在新的结构类型里。被嵌入的类型被称为新的外部类型的内部类型。
  • Java 通常可以通过继承或组合的方式实现嵌入类型要实现的功能。
  • "要嵌入一个类型,只需要声明这个类型的名字就可以了",即 user 而不是 u user, u user 是声明字段
  • 内部类型的方法可以被提升到外部类型直接使用
type user struct {
    name  string
    email string
}
// 注意该方法是 user 的方法(接收者为 user)
func (u *user) notify() {
    fmt.Println("notify", *u)
}

type admin struct {
    // 嵌入类型: "要嵌入一个类型,只需要声明这个类型的名字就可以了"
    // 注意:不是 u user, u user 是声明字段
    // user 是外部类型 admin 的内部类型
    user
    level string
}

func main() {
    ad := admin{
        user: user{"nana", "110@qq.com"},
        level: "super",
    }
    // 我们可以直接访问内部类型的方法
    ad.user.notify() // notify {nana 110@qq.com}
    // 内部类型的方法也被提升到外部类型
    ad.notify() // notify {nana 110@qq.com}
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • 今天上午有一个广播电台直播,想把自己打扮的美美哒,无奈我不懂得化妆,邀请女儿来帮忙,女儿听了大喜,平时经常喜欢给我...
    窦淑明阅读 254评论 4 4
  • 最近老是做梦,天南海北,时光错乱。一合上眼,身心就像风中的树叶般,飘飘悠悠的,不知去往何方。这一日,我发了一个...
    香巴波大阅读 211评论 0 1
  • (原创 2017-10-07 石法武博士 石法武自然疗法) 所有癌症都是从单细胞癌变来的 癌症(临床确诊)源于在致...
    7de21fed4386阅读 963评论 0 1
  • 今天
    jackjeyis阅读 209评论 0 0