Go基础语法

OOP面向对象

Go语言本身不是面向对象的语言,但是可以通过一些方法来模拟对象

面向对象的思维就是分类思维

继承

// 定义一个父类结构体
type Person struct {
name string
age int
} // 定义一个子类结构体
type Student struct {
Person //匿名变量,可以实现继承的效果
school string //子类自己的属性
} func main() {
p1 := Person{"kuangsheng", 18}
fmt.Println(p1.name) // go语言有提升字段的特性
//什么意思呢 对于Student类Person属性就是匿名的 那么Person中的属性 name age就是提升字段
//也就是说 对于Student的实例 可以直接访问 不必通过Person
s1 := Student{Person{"zhangsan", 20}, "xigongda"}
fmt.Println(s1.name) //直接访问 Person的name var s2 Student
s2.name = "lisi"
s2.age = 12
s2.school = "中科大"
fmt.Println(s2)
}

结构体的嵌套分为两种关系:

  1. 模拟继承性
  2. 模拟聚合关系

不同在于 子类结构体使用父类结构体 是是不是匿名的

匿名则为1 实现了继承的效果,命名呢 是2 需要通过父类结构体名才能访问

方法

Go语言同时拥有函数和方法

  • 函数是所有对象都可以调用

  • 方法中多了一个接受者参数,所以只能这个接受者才能使用

  • 接受者可以是一个类型也可以是类型的指针

  • 方法名可以重复,函数名唯一

    type Dog struct {
    name string
    age int
    } type Cat struct {
    name string
    age int
    } func (Dog) eat() {
    fmt.Println("狗子吃饭了")
    } //方法可以重名 但 接受者要不同
    func (cat Cat) eat() {
    fmt.Println("猫咪要吃饭了")
    } func main() { dog := Dog{"尼古拉斯", 1}
    dog.eat() cat := Cat{"lili", 2}
    cat.eat() //eat() 因为有收受者 不能够单独调用哦
    }

重写

子类重写父类的方法 override

type Animal struct {
name string
age int
} func (an Animal) eat() {
fmt.Println(an.name, "吃饭了")
} func (an Animal) sleep() {
fmt.Println(an.name, "睡觉了")
} type Dog struct {
Animal
} type Cat struct {
color string
Animal
} // 子类重写父类的放
func (cat Cat) eat() {
fmt.Println(cat.name, "吃饭了喵喵喵")
} func main() {
dog := Dog{Animal{"wangcai", 1}}
dog.eat()
dog.sleep() cat := Cat{"red", Animal{"秘密", 1}}
cat.eat()
cat.sleep()
}

接口

接口是只做定义、不做具体的方法实现

type Usb interface {
outPut()
inPut()
} /*
go语言不需要显示实现接口
实现接口中的全部方法就是实现了接口
接口和类的关系是非侵入式的
*/
type Mouse struct {
name string
} func (mouse Mouse) outPut() {
fmt.Println(mouse.name, "鼠标的输出")
} func (mouse Mouse) inPut() {
fmt.Println(mouse.name, "鼠标的输入")
} type KeyBord struct {
name string
} func (kb KeyBord) outPut() {
fmt.Println(kb.name, "键盘的输出")
} func (kb KeyBord) inPut() {
fmt.Println(kb.name, "键盘的输入")
} func test(usb Usb) {
usb.outPut()
usb.inPut()
} func main() {
mouse := Mouse{
"罗技",
}
//通过传入接口实现类,来进行具体方法的调用
test(mouse) kb := KeyBord{"雷柏"}
test(kb) //定义一个接口 将实现类赋值给接口 有多态的意思了 但是不能调用
//实现类的属性 可以使用方法哦
var usb Usb
usb = kb
test(usb)
//fmt.Println(usb)
//usb.outPut()
//usb.inPut() }

接口实现多态

一个事务拥有多个形态

比如下方 Dog2的变量 即是Dog2又是Anima

ype Anima interface {
eat()
sleep()
} type Dog2 struct {
name string
} func (d Dog2) eat() {
fmt.Println(d.name, "吃饭")
} func (d Dog2) sleep() {
fmt.Println(d.name, "睡觉")
} func test1(anima Anima) {
anima.eat()
} func main() {
//创建Dog变量
dog := Dog2{"大黄"}
dog.eat()
dog.sleep() //实现了接口Anima的Dog2 可以直接传入到Anima类型中 从而调用接口类的方法
test1(dog) var a Anima
a = dog
fmt.Println(a)
a.sleep()
a.eat() }

空接口

相当于java中的object 可以容纳/成为任何类型

// 空接口  接口中不包含任何方法
type A interface {
} type Pig struct {
name string
} func (p Pig) ai() {
fmt.Println("我是佩奇")
} type Monkey struct {
name string
} func testPig(a A) {
fmt.Println(a)
} func main() {
//空接口可以将任意类型地对象赋值给他
var a1 A = Pig{name: "佩奇"}
var a2 A = Monkey{name: "孙"}
var a3 A = "nihao"
var a4 A = 12
fmt.Println(a1)
fmt.Println(a2)
fmt.Println(a3)
fmt.Println(a4)
testPig(a1)
testPig(a2)
testPig(a3)
testPig(a4)
testPig(a4) //所以 空接口可以作为参数 容纳任何类型
map1 := make(map[string]interface{})
map1["name"] = "zhangsan"
map1["age"] = 12
fmt.Println(map1) //切片也可以 但数组不行类型只能唯一
arr := make([]interface{}, 0, 5)
arr = append(arr, 1, "字符床", false)
fmt.Println(arr) shu := [2]interface{}{1, "3"}
fmt.Println(shu) var nums [4]interface{}
nums[0] = 1
nums[1] = "nihaop"
nums[2] = false
fmt.Println(nums)
fmt.Printf("%T", nums) //[4]interface {} }

接口继承

还可以多继承

type A interface {
test1()
} type B interface {
test2()
} type C interface {
//使用匿名变量继承接口A和B
A
B
test3()
} // 实现接口C
type Tiger struct {
} // 如果只重写了test3方法并不能实现C接口的继承
// 而是要接口C中的AB接口的方法全部重写
func (t Tiger) test3() {
fmt.Println("test3") }
func (t Tiger) test2() {
fmt.Println("test2") }
func (t Tiger) test1() {
fmt.Println("test3")
} func main() { var tiger Tiger = Tiger{}
tiger.test1()
tiger.test2()
tiger.test3()
fmt.Printf("%p\n", &tiger) //接口C继承了AB 才可以调用全部方法
//var a A = tiger只能调用test1
//var b B = tiger只能调用test2
var c C = tiger
c.test1()
c.test2()
c.test3() }

接口断言

其实就是一个判断 检查空接口类型接受的值是什么类型的

// 创建一个空接口 以免后面使用 iterface{}这样  相当于简写为i
type I interface {
} func assert(i I) {
s, ok := i.(int)
if ok {
fmt.Println("int:", s)
} else {
fmt.Println("不是int")
} } func main() { assert("234")
}
// 创建一个空接口 以免后面使用 iterface{}这样  相当于简写为i
type I interface {
} func assert(i I) {
switch i.(type) { //i.(type)可以直接获取接受值的类型
case string:
fmt.Println("string类型")
case int:
fmt.Println("int类型")
case bool:
fmt.Println("bool类型")
case I: //空接口一般要放在空类型前 因为case是从上往下 有一个符号便结束
fmt.Println("空接口类型")
case nil:
fmt.Println("nil的")
default:
fmt.Println("其他")
} } func main() { var nums = [3]interface{}{2, "34", 34}
assert(nums)
}

type别名

语法 : type 新类型名 旧类型名

​ type 新名字=旧名字

/ 在此处相当于定义了一个新的MyInt类型 不过具有int的特性
type MyInt int func main() { var a MyInt = 2
var b int = 3
//fmt.Println(a+b) 由于a和b的类型不一致是无法直接进行运算的
c := int(a)
fmt.Println(b + c) //将int改名为myint 类型还是int 名字不一样
type myint = int
var d myint = 4
var e int = 5
fmt.Println(d + e) }

Go_day05的更多相关文章

随机推荐

  1. java问题解答

    因为子类继承自父类,会沿用父类的东西(没被覆盖的函数以及可见的成员变量等),而这些东西子类是没有的,需要先初始化父类才能被使用 子类构造方法中调用父类构造方法,一个作用是可以给父类构造方法传递实参,给 ...

  2. nuxt项目中使用store

    首先初始化创建一个nuxt项目 nuxt项目创建以后,内部已自动集成store,所以无需再单独安装和引入 在根目录的store文件夹下新建文件,例如home.js //home.js export c ...

  3. Word08 创新产品展示说明会邀请函office真题

    1.课程的讲解之前,先来对题目进行分析,首先需要在考生文件夹下,将Wrod素材.docx文件另存为Word.docx,后续操作均基于此文件,否则不得分. 2.这一步非常的简单,打开下载素材文件,在[文 ...

  4. ABAP 选择屏幕内的组件以及使用

    选择屏幕组件 主要记录了ABAP编程中选择屏幕常用的组件 选择框 范围选择框 radio单选 check选择 单行展现 配合radio和check使用较多 下拉框 自定义下拉框 按钮 文件框 文字帮助 ...

  5. stm32 窗口看门狗

    窗口看门狗一般要在几十毫秒后开始喂狗 窗口看门狗在执行0x40时会调用回调函数, 回调函数可以执行喂门狗,否则会执行到0x3F直接复位 参考链接: https://blog.csdn.net/weix ...

  6. Mac如何用鼠标快速锁屏

    锁屏谁不会啊?本来写这篇文章,感觉自己太多余,但用鼠标直接锁屏就有点小意思,Mac对于很多人来说非常模式,通常是商务.设计这类人事在使用,对于新手而言,它的功能过于隐藏,那么Mac要如何达到快速锁屏呢 ...

  7. 小程序ios设置map圆角不生效的问题解决方案

    给map组件加个view外框,设置如下样式即可 border-radius:10rpx; overflow:hidden; transform: translateY(0);

  8. 简单的WPF客户端应用开发

    1.使用vs创建一个新项目,选择wpf应用 2.创建好项目,在视图=>工具箱,选择要使用的部件 3.单击部件可以改变部件的显示信息,即content的内容就是显示的信息,name为部件的名称,在 ...

  9. IQueryable 和 IEnumerable 的区别

    讲一讲 IQueryable 和 IEnumerable 的区别. 我们会在使用 LINQ 查询方法之后,又使用 ToList 等方法,将查询结果转换成集合. 如果我们不使用 ToList 呢? 比如 ...

  10. int 和vachar后面的数字代表的含义

    在创建数据表的时候,我们经常会给每一个字段设置一个长度,例如:int(5).varchar(10) 等等,但是他们代表的意思是什么呢?是该列允许存储值的最大宽度吗? 场景1:为什么我设置成 int(1 ...