面向对象

  1. 面向对象是软件开发的方法

  2. 泛指现实中一切实体事务,每种事务都具备自己的属性和行为

  3. 将事务的属性、行为抽象出来,描述成计算机事件的设计思想

在golang中表示一个类,使用的是结构体。

封装

golang中的封装,主要是通过类型、方法名称的首字母大小写为主要依据。如果首字母大写,代表将该类型、方法、函数导出,在其他包下,则可以直接使用。反之,如果首字母小写,则只能被相同包的人直接引用。下面是代码示例:

// Package person
// 包 person下,person.go
package person

import "fmt"

// 小写开头,结构体person不导出
type person struct {
    Name string
    age uint8
    sal float32
}

// SetAge 大写字母,方法SetAge导出
func (p *person) SetAge(age uint8) {
    if age > 200 {
        fmt.Println("年龄范围在0-200之间")
    } else {
        p.age = age
    }
}

func (p *person) GetAge() uint8 {
    return p.age
}

func (p *person) SetSal(sal float32) {
    if sal <= 0 {
        fmt.Println("薪水不可小于零")
    } else {
        p.sal = sal
    }
}

// 使用工厂模式创建对象
func NewPerson(name string) *person{
    return &person{
        Name: name,
    }
}

继承

继承可以解决代码复用的问题,当多个结构体出现相同的字段、方法,可以从这些结构体中抽象出一个新的结构体,在这个结构体中定义这些共用字段、方法。最后所有的结构体都去继承这个结构体即可。

golang没有完整严格的地继承方式(耦合更低),他总是优先使用组合方式——可以通过内嵌另一个结构体的方式实现继承。当结构体内嵌了另一个结构体,则当前的结构体可以直接访问内嵌的结构体中的所有属性和方法,代码如下:

总结:

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

  2. 匿名结构体的字段访问可以简化:dog.Animal.Name 可以简化为dog.Name

  3. 当结构体与匿名结构体有相同的字段或者方法时,编译器采用就近访问原则访问,如果希望访问匿名结构体的字段与方法,可以使用匿名结构体的名称区分,比如:Eat()AnimalDog中都含有此方法,默认使用dog.Eat()会调用Dog的方法(就近原则),如果想要调用匿名结构体的Eat(),需要使用dog.Animal.Eat()

  4. 结构体嵌入两个或者多个匿名结构体,如果两个匿名结构体具有相同的字段和方法(同时结构体本身没有这个字段与方法),在访问时就必须明确指定匿名结构体名字,否则编译器报错。比如,结构体A同时继承BC,且BC都有方法Hello(),当A结构体变量访问 Hello()时,必须且只能通过a.B.Hello()或者 a.C.Hello()进行访问,如果使用a.hello()则会报错

嵌入基本数据类型

多重继承

如果一个struct嵌套了多个匿名结构体,那么该结构体可以直接访问嵌套的匿名结构体的字段与方法,从而实现多继承。

尽量不使用多重继承

接口

interface类型可以定义一组方法,但是这些方法不需要实现,并且interface不可以包含任何变量。到某个自定义类型要使用的时候,通过定义所有的接口方法(也就是实现方法),来完成接口实现的效果。

注意事项:

  1. 接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量

  2. 接口中所有的方法都没有方法体,即都是没有实现的方法

  3. 接口中不能含有任何变量或常量

  4. 在golang中,一个自定义类型需要将某个接口的所有方法都实现,我们才说这个类型实现了该接口

  5. 只要是自定义类型都是可以实现接口,不仅仅是结构体类型

  6. 一个自定义类型可以实现多个接口

  7. 一个接口可以继承多个别的接口,如果要实现接口A,那么他所继承的B以及C接口中的方法也必须实现

  8. 如果接口继承之间含有相同的方法名,会报错(go1.7不报错

示例:

多态

**类型断言:**由于接口是一般类型,不知道具体类型,如果需要具体类型,就需要使用类型断言

  1. 要进行类型断言的变量本身就是这个类型,不是类型强转,类型断言只是断言类型

  2. 如果类型不匹配,类型断言会抛出panic: interface conversion

  3. 所以,在进行类型断言时,一定要确定类型

  4. 类型断言之前进行检测机制:

  5. switch + 类型断言

最后更新于

这有帮助吗?