1. Go语言中的OOP
package main
import "fmt"
/*
面向对象:OOP
Go语言的结构体嵌套:
1. 模拟继承性:is - a
type A struct {
field
}
type B struct {
A // 匿名字段
}
2. 模拟聚合关系:has - a
type C struct {
field
}
type D struct {
c C // 聚合关系
}
*/
// 定义父类
type Person struct {
name string
age int
}
// 定义子类
type Student struct {
Person // 模拟继承结构
school string // 子类的新增属性
}
func main() {
// 创建父类的对象
p1 := Person{name: "zhangsan", age: 30}
fmt.Println(p1.name, p1.age)
// 创建子类的对象
s1 := Student{Person{"lisi", 18}, "ECNU"}
fmt.Println(s1)
var s2 Student
s2.Person.name = "wangwu"
s2.Person.age = 28
s2.school = "YTU"
fmt.Println(s2)
// 由于Person作为了Student中的匿名字段,因此Person中的字段可以通过Student直接访问,被称为提升字段
s2.name = "zhaoliu"
s2.age = 16
fmt.Println(s2)
}
2. 继承中的方法
package main
import "fmt"
// 定义父类
type Person struct {
name string
age int
}
// 定义子类
type Student struct {
Person
school string
}
func (p Person) eat() {
fmt.Println("父类的方法,eat")
}
func (s Student) study() {
fmt.Println("学生中学习")
}
func (s Student) eat() {
fmt.Println("子类重写的方法,eat")
}
func main() {
p1 := Person{"zhangsan", 30}
fmt.Println(p1.name, p1.age)
p1.eat()
s1 := Student{Person{"lisi", 18}, "YTU"}
fmt.Println(s1.name, s1.age, s1.school)
// 当子类没重写父类方法时,可以访问父类的方法
s1.eat()
s1.study()
}
3. 接口
package main
import "fmt"
/*
接口:interface
在Go中,接口是一组方法签名
当某个类型为这个接口中的所有方法提供了方法的实现,它被称为实现接口
Go语言中,接口和类型的实现关系是非侵入式的
*/
// 定义接口
type USB interface {
start() // 开始工作
end() // 结束工作
}
// 实现类
type Mouse struct {
name string
}
type FlashDisk struct {
name string
}
func (m Mouse) start() {
fmt.Println(m.name, "鼠标开始工作")
}
func (m Mouse) end() {
fmt.Println(m.name, "鼠标结束工作")
}
func (f FlashDisk) start() {
fmt.Println(f.name, "U盘开始工作")
}
func (f FlashDisk) end() {
fmt.Println(f.name, "U盘结束工作")
}
func (f FlashDisk) deleteData() {
fmt.Println(f.name, "U盘删除数据")
}
// 当需要使用接口类型的对象时,可以用任意实现类对象来代替
func testInterface(usb USB) {
usb.start()
usb.end()
}
func main() {
m1 := Mouse{"逻辑"}
testInterface(m1)
f1 := FlashDisk{"闪迪"}
testInterface(f1)
f1.deleteData()
var usb USB
usb = m1
usb.start()
usb.end()
}
接口的用法:
- 一个函数如果接受接口类型为参数,那么实际上可以传入该接口的任意实现类型对象作为参数
- 定义一个接口类型,实际上可以赋值为任意实现类的对象
4. 接口嵌套
package main
import "fmt"
type A interface {
test1()
}
type B interface {
test2()
}
type C interface {
A
B
test3()
}
type Cat struct {
}
func (c Cat) test1() {
fmt.Println("test1()...")
}
func (c Cat) test2() {
fmt.Println("test2()...")
}
func (c Cat) test3() {
fmt.Println("test3 ()...")
}
func main() {
var cat Cat = Cat{}
cat.test1()
cat.test2()
cat.test3()
fmt.Println("------------------------")
var a1 A = cat
a1.test1()
fmt.Println("------------------------")
var b1 B = cat
b1.test2()
fmt.Println("------------------------")
var c1 C = cat
c1.test1()
c1.test2()
c1.test3()
fmt.Println("------------------------")
var a2 A = c1
a2.test1()
}
5. 接口断言
方式一:
- instance := 接口对象.(实际类型) // 不安全,会panic()
- Instance, ok := 接口对象.(实际类型) //安全
方式二:
switch instance := 接口对象.(实际类型) {
case 实际类型1:
...
case 实际类型2:
...
...
}