Go中的类相关操作

140 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情

二、类相关操作

go语言支持类的操作,但是没有class关键字,使用struct来模拟类

1.封装-绑定方法

Person类,绑定方法:Eat,Run,Laugh, 成员

public,private

package main
​
import "fmt"/*
class Person {
public :
    string name
    int age
​
public :
    Eat() {
        xxx
    }
}
​
*///任何type的类型,都可以绑定方法
type MyInt1 intfunc (mi *MyInt1) printMyInt() {
    fmt.Println("MyInt value is:", *mi)
}
​
type Person struct {
    //成员属性:
    name   string
    age    int
    gender string
    score  float64
}
/*
Person:::Eat() {
    
}
*///在类外面绑定方法
func (this *Person) Eat() {
    //fmt.Println("Person is eating")
    //类的方法,可以使用自己的成员
    //fmt.Println(this.name + " is eating!")
    this.name = "Duke"
}
​
func (this Person) Eat2() {
    fmt.Println("Person is eating")
    //类的方法,可以使用自己的成员
    this.name = "Duke"
}
​
func main() {
    lily := Person{
        name:   "Lily",
        age:    30,
        gender: "女生",
        score:  10,
    }
​
    lily1 := lily
​
    fmt.Println("Eat,使用p *Person,修改name的值 ...")
    fmt.Println("修改前lily:", lily) //lily
    lily.Eat()
    fmt.Println("修改后lily:", lily) //Duke
​
    fmt.Println("Eat2,使用p Person,但是不是指针 ...")
    fmt.Println("修改前lily:", lily1) //lily
    lily1.Eat2()
    fmt.Println("修改后lily:", lily1) //lilyvar myint1 MyInt1 = 100
    myint1.printMyInt()
}
​

image.png

2. 类继承

package main
​
import "fmt"type Human struct {
    //成员属性:
    name   string
    age    int
    gender string
}
​
//在类外面绑定方法
func (this *Human) Eat() {
    fmt.Println("this is :", this.name)
}
​
//定义一个学生类,去嵌套一个Hum
type Student1 struct {
    hum    Human //包含Human类型的变量, 此时是类的嵌套
    score  float64
    school string
}
​
//定义一个老师,去继承Human
type Teacher struct {
    Human          //直接写Huam类型,没有字段名字
    subject string //学科
}
​
func main() {
    s1 := Student1{
        hum: Human{
            name:   "Lily",
            age:    18,
            gender: "女生",
        },
        school: "昌平一中",
    }
​
    fmt.Println("s1.name:", s1.hum.name)
    fmt.Println("s1.school:", s1.school)
​
    t1 := Teacher{}
    t1.subject = "语文"
    t1.name = "荣老师" //下面这几个字段都是继承自Human
    t1.age = 35
    t1.gender = "女生"
​
    fmt.Println("t1 :", t1)
    t1.Eat()
​
    //继承的时候,虽然我们没有定义字段名字,但是会自动创建一个默认的同名字段
    //这是为了在子类中依然可以操作父类,因为:子类父类可能出现同名的字段
    fmt.Println("t1.Human.name:", t1.Human.name)
}
​

image.png

访问权限

在go语言中,权限都是通过首字母大小来控制

  1. import ==》 如果包名不同,那么只有大写字母开头的才是public的
  2. 对于类里面的成员、方法===》只有大写开头的才能在其他包中使用

在C++中,实现接口的时候,使用纯虚函数代替接口,在go语言中,有专门的关键字 interface来代表接口.,interface不仅仅是用于处理多态的,它可以接受任意的数据类型,有点类似void

3. interface(接口)

package main
​
import "fmt"

func main() {
    //func Println(a ...interface{}) (n int, err error) {
    fmt.Println("")
​
    //var i,j,k int
    //定义三个接口类型
    var i, j, k interface{}
    names := []string{"duke", "lily"}
    i = names
    fmt.Println("i代表切片数组:", i)
​
    age := 20
    j = age
    fmt.Println("j代表数字:", j)
​
    str := "hello"
    k = str
    fmt.Println("k代表字符串:", k)
​
}
​

image.png

在C++中,实现接口的时候,使用纯虚函数代替接口,在go语言中,有专门的关键字 interface来代表接口,interface不仅仅是用于处理多态的,它可以接受任意的数据类型,有点类似void

package main
​
import "fmt"func main() {
    //func Println(a ...interface{}) (n int, err error) {
    fmt.Println("")
​
    //var i,j,k int
    //定义三个接口类型
    var i, j, k interface{}
    names := []string{"duke", "lily"}
    i = names
    fmt.Println("i代表切片数组:", i)
​
    age := 20
    j = age
    fmt.Println("j代表数字:", j)
​
    str := "hello"
    k = str
    fmt.Println("k代表字符串:", k)
​
    //我们现在只知道k是interface,但是不能够明确知道它代表的数据的类型
    kvalue, ok := k.(int)  //<<<==== 做类型的二次确认
    if !ok {
        fmt.Println("k不是int")
    } else {
        fmt.Println("k是int, 值为:", kvalue)
    }
​
    //最常用的场景: 把interface当成一个函数的参数,(类似于print),使用switch来判断用户输入的不同类型
    //根据不同类型,做相应逻辑处理//创建一个具有三个接口类型的切片
    array := make([]interface{}, 3)
    array[0] = 1
    array[1] = "Hello world"
    array[2] = 3.14for _, value := range array {
        //可以获取当前接口的真正数据类型
        switch v := value.(type) {
        case int:
            fmt.Printf("当前类型为int, 内容为:%d\n", v)
        case string:
            fmt.Printf("当前类型为string, 内容为: %s\n", v)
        case bool:
            fmt.Printf("当前类型为bool, 内容为: %v\n", v) //%v可以自动推到输出类型
        default:
            fmt.Println("不是合理的数据类型")
        }
    }
}