• golang面向对象


    一、方法

    1、方法是作用在指定的数据类型上,和指定的数据类型绑定,因此自定义类型都可以有方法,而不仅仅是struct;

    2、方法的申明和格式调用:

    package main
    import (
        "fmt"
    )
    
    type Person struct{
        Name string
    }
    
    func (p Person) test(){
        fmt.Println(p.Name)
    }
    
    func main(){
        p := Person{Name: "Tom"}
        p.test()
    }

    注意:结构体对象传入方法中是值传递,和函数传递参数一样。如果在方法中改变结构体变量的值,可以通过结构体指针的方式来处理。

    package main
    import (
        "fmt"
    )
    
    type Person struct{
        Name string
    }
    
    func (p *Person) test(){
        fmt.Println((*p).Name)
    }
    
    func main(){
        p := &Person{Name: "Tom"}
        p.test()
    }

    二、封装:

    1、什么是封装?

    封装就是把抽象出的字段和对字段的操作封装在一起,数据被保护在内部,程序的其它包只有通过被授权的操作方法才能对字段就行操作。

    2、封装的好处:

    1)隐藏实现细节;

    2)可以对数据进行验证,保证数据安全合理。

    3、golang中如何实现封装?

    package main
    import (
        "fmt"
    )
    
    type person struct{
        Name string
        age int
    }
    
    func NewPerson(name string) *person {
        p := person{
            Name: name,
        }
    
        return &p
    }
    
    func (p *person) SetAge(age int){
        if age > 0 && age < 150{
            (*p).age = age
        } else {
            fmt.Println("对不起,你输入的年龄范围不正确。")
        }
    }
    
    func (p *person) GetAge() int {
        return (*p).age
    }
    
    func main(){
        p := NewPerson("Tom")
        p.SetAge(22)
        fmt.Println(p.Name)
        fmt.Println(p.GetAge)
        fmt.Println(*p)
    }
    
    // Tom
    // 0xbc5a60
    // {Tom 22}

    三、继承

    当多个结构体存在相同的属性和方法时可以从这些结构体中抽象出结构体,在该结构体中定义这些相同的属性和方法,其它的结构体中不需要重新定义这些属性和方法,只需要嵌入一个匿名结构体即可。

    也就是说,在golang中如果一个struct嵌套了另一个匿名结构体,那个这个struct可以直接访问这个匿名结构的属性和方法,从而实现了继承特性。

    继承的优点:

    1、提高代码的复用性和扩展性;

    package main
    import (
        "fmt"
    )
    
    type Animal struct{
        Age int
        Weight float32
    }
    
    func (an *Animal) Shout(){
        fmt.Println("我可以大声喊叫")
    }
    
    func (an *Animal) ShowInfo(){
        fmt.Println("动物的年龄是:%v,动物的体重是:%v", an.Age, an.Weight)
    }
    
    type Cat struct{
        Animal
    }
    
    func (c *Cat) scratch(){
        fmt.Println("我是小猫,我可以挠人。")
    }
    
    func main(){
        cat := &Cat{}
        cat.Animal.Age = 3
        cat.Animal.Weight = 10.6
        cat.Animal.Shout()
        cat.Animal.ShowInfo()
        cat.scratch()
    }

    注意事项:

    1、结构体可以使用嵌套匿名结构体所有的字段和方法,即:首字母大写和小写的字段、方法都可以使用;

    2、匿名结构体字段访问可以简化;

    3、当结构体和匿名结构体有相同的字段和方法时,编译器采用就近访问原则进行访问,如果希望访问匿名结构体属性和方法,可以通过匿名结构体名来区分;

    4、golang中支持多继承;

    package main
    import (
        "fmt"
    )
    
    type A struct{
        a1 string
        a2 int
    }
    
    type B struct{
        b1 string
        b2 int
    }
    
    type C struct{
        A
        B
    }
    
    func main(){
        c := C{A{"a1", 10}, B{"b1", 20}}
        fmt.Println(c)
    }

    5、如果嵌入的匿名结构体有相同的属性名或方法,则在访问时需要通过匿名结构体类型名来区分;

    6、结构体的匿名字段可以是基本数据类型;

    package main
    import (
        "fmt"
    )
    
    type A struct{
        a1 string
        a2 int
    }
    
    type B struct{
        b1 string
        b2 int
    }
    
    type C struct{
        A
        B
        int
    }
    
    func main(){
        c := C{A{"a1", 10}, B{"b1", 20}, 888}
        fmt.Println(c.a1)
        fmt.Println(c.a2)
        fmt.Println(c.b1)
        fmt.Println(c.b2)
        fmt.Println(c.A.a1)
        fmt.Println(c.A.a2)
        fmt.Println(c.B.b1)
        fmt.Println(c.B.b2)
        fmt.Println(c.int)
    }
    
    //a1
    //10
    //b1
    //20
    //a1
    //10
    //b1
    //20
    //888

    7、嵌套匿名结构体后,可以在创建结构体变量时直接指定各个匿名结构体字段的值;

    8、嵌入匿名结构体的指针也是可以的;

    9、结构体的字段可以是结构体类型的。

    package main
    import (
        "fmt"
    )
    
    type A struct{
        a1 string
        a2 int
    }
    
    type B struct{
        b1 string
        b2 int
    }
    
    type C struct{
        A
        B
        int
    }
    
    type D struct{
        a int
        b B
    }
    
    func main(){
        d := D{11, B{"BB", 66}}
        fmt.Println(d)
        fmt.Println(d.b.b1)
    }
    
    // {11 {BB 66}}
    // BB

    四、多态

    变量、实例具有多种形态。面向对象的第三大特征,在golang中,多态是通过接口实现的,可以按照统一的接口来调用不同的实现,这时接口变量就呈现不同的形态。

    package main
    import (
        "fmt"
    )
    
    type Chinese struct{
    
    }
    
    type American struct{
        
    }
    
    type SayHello interface {
        say()
    }
    
    func (c Chinese) say(){
        fmt.Println("中国人说中文")
    }
    
    func (a American) say(){
        fmt.Println("美国人说英文")
    }
    
    func greet(s SayHello){
        s.say()
    }
    
    func main(){
        c := Chinese{}
        a := American{}
        greet(c)
        greet(a)
    }
    
    //中国人说中文
    //美国人说英文

    接口体现多态特征:

    1、多态参数:s叫多态参数

    func greet(s SayHello){
        s.say()
    }

    2、多态数组

        var arr [3]SayHello
        arr[0] = Chinese{"丽丽"}
        arr[1] = Chinese{"菲菲"}
        arr[2] = American{"Rose"}
        fmt.Println(arr)
    package main
    import (
        "fmt"
    )
    
    type Chinese struct{
        name string
    }
    
    type American struct{
        name string
    }
    
    type SayHello interface {
        say()
    }
    
    func (c Chinese) say(){
        fmt.Println("中国人说中文")
    }
    
    func (a American) say(){
        fmt.Println("美国人说英文")
    }
    
    func greet(s SayHello){
        s.say()
    }
    
    func main(){
        var arr [3]SayHello
        arr[0] = Chinese{"丽丽"}
        arr[1] = Chinese{"菲菲"}
        arr[2] = American{"Rose"}
        fmt.Println(arr)
    }

     

  • 相关阅读:
    React-Admin后台管理模板|react18+arco+zustand后台解决方案
    腾讯云SSH连接不上的一个解决办法
    计网第五章(运输层)(四)(TCP的流量控制)
    二次型与线性空间
    微信小程序:全新独家云开发微群人脉
    CodeLab:一款让你体验丝滑般的云化JupyterLab
    微信小程序自定义顶部导航栏
    论文精读《OFT: Orthographic Feature Transform for Monocular 3D Object Detection》
    vue页面缓存解决方案
    【Python】Python中变量的类型是动态的,如何优雅获取变量类型?
  • 原文地址:https://www.cnblogs.com/arichman/p/16907459.html