第04天(面对对象编程)_03

2019-12-31  本文已影响0人  lucas777

11_方法的继承.go

package main

import "fmt"

type Person struct {
    name string //名字
    sex  byte   //性别, 字符类型
    age  int    //年龄
}

//Person类型,实现了一个方法
func (tmp *Person) PrintInfo() {
    fmt.Printf("name=%s, sex=%c, age=%d\n", tmp.name, tmp.sex, tmp.age)
}

//有个学生,继承Person字段,成员和方法都继承了
type Student struct {
    Person //匿名字段
    id     int
    addr   string
}

func main() {
    s := Student{Person{"mike", 'm', 18}, 666, "bj"}
    s.PrintInfo()
}

12_方法的重写.go

package main

import "fmt"

type Person struct {
    name string //名字
    sex  byte   //性别, 字符类型
    age  int    //年龄
}

//Person类型,实现了一个方法
func (tmp *Person) PrintInfo() {
    fmt.Printf("name=%s, sex=%c, age=%d\n", tmp.name, tmp.sex, tmp.age)
}

//有个学生,继承Person字段,成员和方法都继承了
type Student struct {
    Person //匿名字段
    id     int
    addr   string
}

//Student也实现了一个方法,这个方法和Person方法同名,这种方法叫重写
func (tmp *Student) PrintInfo() {
    fmt.Println("Student: tmp = ", tmp)
}

func main() {
    s := Student{Person{"mike", 'm', 18}, 666, "bj"}
    //就近原则:先找本作用域的方法,找不到再用继承的方法
    s.PrintInfo() //到底调用的是Person, 还是Student, 结论是Student

    //显式调用继承的方法
    s.Person.PrintInfo()
}

13_方法值.go

package main

import "fmt"

type Person struct {
    name string //名字
    sex  byte   //性别, 字符类型
    age  int    //年龄
}

func (p Person) SetInfoValue() {
    fmt.Printf("SetInfoValue: %p, %v\n", &p, p)
}

func (p *Person) SetInfoPointer() {
    fmt.Printf("SetInfoPointer: %p, %v\n", p, p)
}

func main() {
    p := Person{"mike", 'm', 18}
    fmt.Printf("main: %p, %v\n", &p, p)

    p.SetInfoPointer() //传统调用方式

    //保存方式入口地址
    pFunc := p.SetInfoPointer //这个就是方法值,调用函数时,无需再传递接收者,隐藏了接收者
    pFunc()                   //等价于 p.SetInfoPointer()

    vFunc := p.SetInfoValue
    vFunc() //等价于 p.SetInfoValue()
}

14_方法表达式.go

package main

import "fmt"

type Person struct {
    name string //名字
    sex  byte   //性别, 字符类型
    age  int    //年龄
}

func (p Person) SetInfoValue() {
    fmt.Printf("SetInfoValue: %p, %v\n", &p, p)
}

func (p *Person) SetInfoPointer() {
    fmt.Printf("SetInfoPointer: %p, %v\n", p, p)
}

func main() {
    p := Person{"mike", 'm', 18}
    fmt.Printf("main: %p, %v\n", &p, p)

    //方法值   f := p.SetInfoPointer //隐藏了接收者
    //方法表达式
    f := (*Person).SetInfoPointer
    f(&p) //显式把接收者传递过去 ====》 p.SetInfoPointer()

    f2 := (Person).SetInfoValue
    f2(p) //显式把接收者传递过去 ====》 p.SetInfoValue()
}

15_接口的定义和实现.go

package main

import "fmt"

//定义接口类型
type Humaner interface {
    //方法,只有声明,没有实现,由别的类型(自定义类型)实现
    sayhi()
}

type Student struct {
    name string
    id   int
}

//Student实现了此方法
func (tmp *Student) sayhi() {
    fmt.Printf("Student[%s, %d] sayhi\n", tmp.name, tmp.id)
}

type Teacher struct {
    addr  string
    group string
}

//Teacher实现了此方法
func (tmp *Teacher) sayhi() {
    fmt.Printf("Teacher[%s, %s] sayhi\n", tmp.addr, tmp.group)
}

type MyStr string

//MyStr实现了此方法
func (tmp *MyStr) sayhi() {
    fmt.Printf("MyStr[%s] sayhi\n", *tmp)
}

//定义一个普通函数,函数的参数为接口类型
//只有一个函数,可以有不同表现,多态
func WhoSayHi(i Humaner) {
    i.sayhi()
}

func main() {
    s := &Student{"mike", 666}
    t := &Teacher{"bj", "go"}
    var str MyStr = "hello mike"

    //调用同一函数,不同表现,多态,多种形态
    WhoSayHi(s)
    WhoSayHi(t)
    WhoSayHi(&str)

    //创建一个切片
    x := make([]Humaner, 3)
    x[0] = s
    x[1] = t
    x[2] = &str

    //第一个返回下标,第二个返回下标所对应的值
    for _, i := range x {
        i.sayhi()
    }

}

func main01() {
    //定义接口类型的变量
    var i Humaner

    //只是实现了此接口方法的类型,那么这个类型的变量(接收者类型)就可以给i赋值
    s := &Student{"mike", 666}
    i = s
    i.sayhi()

    t := &Teacher{"bj", "go"}
    i = t
    i.sayhi()

    var str MyStr = "hello mike"
    i = &str
    i.sayhi()
}
上一篇 下一篇

猜你喜欢

热点阅读