1. 方法的定义
package main import "fmt" func main() { /* 方法:method 一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。 所有给定类型的方法属于该类型的方法集 语法: //接收者的意思是就是谁能调用我 //接收者表示调用该方法的棘突类型变量,多用类型名首字母小写 func (接受者) 方法名(参数列表)(返回值列表){ } 总结:method,同函数类似,区别需要有接受者。(也就是调用者) 对比函数: A:意义 方法:某个类别的行为功能,需要指定的接受者调用 函数:一段独立功能的代码,可以直接调用 B:语法 方法:方法名可以相同,只要接受者不同 函数:命名不能冲突 */ w1 := Worker{name: "王二狗", age: 30, sex: "男"} w1.work() //王二狗 在工作。。。 w2 := &Worker{name: "Ruby", age: 34, sex: "女"} fmt.Printf("%T ", w2) //*main.Worker w2.work() //Ruby 在工作。。。 w2.rest() //Ruby 在休息。。 w1.rest() //王二狗 在休息。。 w2.printInfo() //工人姓名:Ruby,工人年龄:34,工人性别:女 c1 := Cat{color: "白色的", age: 1} c1.printInfo() //猫咪的颜色:白色的,年龄:1 } //1.定义一个工人结构体 type Worker struct { //字段 name string age int sex string } type Cat struct { color string age int } //2.定义行为方法 func (w Worker) work() { //w = w1 fmt.Println(w.name, "在工作。。。") } //什么时候应该使用指针类型接收者? //需要修改接收者中的值 //接收者是拷贝代价比较大的大对象 //保证一致性,如果有某个方法使用了指针接收者,那么其他的方法也应该使用指针接收者。 //p可以理解为Python中的self,指的是结构体的对象 //根据后面的类型,可以传递值类型和指针类型 //python中的self是引用 func (p *Worker) rest() { //p = w2 ,p = w1的地址 fmt.Println(p.name, "在休息。。") } func (p *Worker) printInfo() { fmt.Printf("工人姓名:%s,工人年龄:%d,工人性别:%s ", p.name, p.age, p.sex) } func (p *Cat) printInfo() { fmt.Printf("猫咪的颜色:%s,年龄:%d ", p.color, p.age) }
2. 匿名字段
package main import "fmt" // 匿名字段 // 字段比较少也比较简单的场景 // 不常用!!! type person struct { string int } func main() { p1 := person{ "yang", 9000, } fmt.Println(p1) fmt.Println(p1.string) fmt.Println(p1.int) }
3. 匿名嵌套
package main import "fmt" // 结构体嵌套 type address struct { province string city string } type workPlace struct { province string city string } type person struct { name string age int address // 匿名嵌套结构体 workPlace // address:address } type company struct { name string address } func main() { p1 := person{ name: "yang", age: 9000, address: address{ province: "山东", city: "威海", }, } fmt.Println(p1) fmt.Println(p1.name, p1.address.city) // fmt.Println(p1.city) //语法糖,匿名嵌套的好处(因为没有名字,所以不知道.什么,只能.字段名) // 先在自己结构体找这个字段,找不到就去匿名嵌套的结构体中查找该字段 fmt.Println(p1.address.city) fmt.Println(p1.workPlace.city) }
4. 继承(go是没有继承这个概念的,可以模拟)
package main import "fmt" func main() { /* OOP中的继承性: 如果两个类(class)存在继承关系,其中一个是子类,另一个作为父类,那么: 1.子类可以直接访问父类的属性和方法 2.子类可以新增自己的属性和方法 3.子类可以重写父类的方法(orverride,就是将父类已有的方法,重新实现) Go语言的结构体嵌套: 1.模拟继承性:is - a type A struct{ field } type B struct{ A //匿名字段 } 2.模拟聚合关系:has - a type C struct{ field } type D struct{ c C //聚合关系 } */ //1.创建Person类型 p1 := Person{name:"王二狗",age:30} fmt.Println(p1.name,p1.age) //父类对象,访问父类的字段属性 p1.eat() //父类对象,访问父类的方法 //2.创建Student类型 s1 := Student{Person{"Ruby",18},"千锋教育"} fmt.Println(s1.name) //s1.Person.name fmt.Println(s1.age) //子类对象,可以直接访问父类的字段,(其实就是提升字段) fmt.Println(s1.school) //子类对象,访问自己新增的字段属性 s1.eat() //子类对象,访问父类的方法 s1.study() //子类对象,访问自己新增的方法 s1.eat() //如果存在方法的重写,子类对象访问重写的方法 } //1.定义一个"父类" type Person struct { name string age int } //2.定义一个"子类" type Student struct { Person //结构体嵌套,模拟继承性 school string } //3.方法 func (p Person) eat(){ fmt.Println("父类的方法,吃窝窝头。。") } func (s Student) study(){ fmt.Println("子类新增的方法,学生学习啦。。。") } func (s Student) eat(){ fmt.Println("子类重写的方法:吃炸鸡喝啤酒。。") }