封装
go语言中可以简单地看作对struct的封装
type Person struct {
name string
}
type Student struct {
name string
}
type Teacher struct {
name string
}
继承
go语言中没有继承,但可以通过“匿名组合”实现继承
结构体继承,方法继承,方法重写
//父类
type Person struct {
name string
age int
}
type Student struct {
Person //匿名继承
//*Person //指针作为匿名字段
//p Person//别名继承
height string
//子类和父类字段重名
name string
}
type Teacher struct {
Person //匿名继承
//*Person //指针作为匿名字段
//p Person//别名继承
sex string
}
//基本类型不能作为对象直接使用,为基本类型绑定方法,需要起别名才可以
type newint int
func (i newint) add(a newint) newint {
return a + 1
}
//方法继承和重写(给结构体绑定方法)
//*代表是否可以读写(修改),*代表接收者为指针
func (p *Person) eat(){
fmt.Println("人类吃饭")
}
func (p *Person) drink(){
fmt.Println("人类喝水")
}
func (p *Student) eat(){
fmt.Println("学生吃饭")
}
func main() {
tea :=Teacher{Person{"人类",1},"男"}
//子类和父类字段重名,默认给子类赋值,给父类赋值需要加父类名称调用
tea.name = "张飞"
tea.Person.name = "大飞"
//子类可以直接使用父类字段
fmt.Println(tea.name)
fmt.Println(tea.age)
fmt.Println(tea.sex)
stu :=Student{Person{"人类",1},"188"}
//方法继承,子类可以直接调用父类方法
stu.drink()
//方法重写,默认执行子类方法
stu.eat()
stu.Person1.eat()
//如果是指针作为匿名字段
var stu Student
//需要new一个空间
stu.Person = new(Person)
//正常模式
(*stu.Person).name = "典韦"
//简易模式
stu.name = "诸葛亮"
fmt.Println(stu.name)
//使用别名调用方法
var newi newint
result :=newi.add(2)
fmt.Println("为int定义别名",result)
}
多态(接口作为参数实现多态)
接口
接口 ,给结构体定义接口,那么必须定义接口里面的所有方法才可以
//定义接口
type IHuman interface {
say()
eat()
}
type Stus struct {
name string
age int
}
type Teas struct {
name string
age int
sex string
}
//结构体实现接口方法1
func (stus *Stus) eat() {
fmt.Println(stus.name, "正在吃饭")
}
//结构体实现接口方法2
func (stus *Stus) say() {
fmt.Println(stus.name, "正在说话")
}
func (tea *Teas) eat() {
fmt.Println(tea.name, "正在吃饭")
}
func (tea *Teas) say() {
fmt.Println(tea.name, "正在说话")
}
//将接口作为函数参数实现多态
func dotest(hu IHuman) {
hu.say()
hu.eat()
}
//测试
func main() {
//多态调用
stus := Stus{"诸葛", 1}
dotest(&stus)
tea := Teas{"老师", 1,"男"}
dotest(&tea)
var h IHuman
h = &stus
h.say()
h.eat()
}
接口继承和转换
//接口继承和转换
type Humans interface {//子集
eat()
}
type Persons interface {//超集
Humans //匿名继承接口
say()
}
type Students struct {
name string
age int
}
func (stus *Students)say() {
fmt.Println(stus.name,"在说话")
}
func (stus *Students)eat() {
fmt.Println(stus.name,"在吃东西")
}
func main() {
var h Humans
stu :=Students{"飞飞",1}
h = &stu
h.eat()
var p Persons
p = &stu
p.eat()
p.say()
//超集中包含所有子集的方法
//超集合赋值给子集,子集不能赋值给超集
h = p
//p = h //这样是不可以的
h.eat()
}
空接口和类型断言
//空接口
var i interface{}
//空接口类型的切片
var ni []interface{}
func test() {
fmt.Println("函数调用")
}
func main() {
//空接口可以接受任意类型数据
i = 10
fmt.Printf("%T\n", i)
fmt.Println(i)
i = "你好"
fmt.Println(i)
fmt.Printf("%T\n", i)
//接口切片可以放任意类型
app := append(ni, 88, "飞飞", 3.23, test)
//里面的值不能直接使用,要通过类型断言才可以
for a := 0; a < len(app); a++ {
fmt.Println(app[a])
}
for _, v := range app {
if value, ok := v.(int); ok {
fmt.Println("int数据", value)
} else if test, ok := v.(func()); ok {
test()
} else if value, ok := v.(string); ok {
fmt.Println("sting数据", value)
}
}
//类型断言
//值,值的判断bool = 接口变量(数据类型)
value, ok := i.(string)
if ok {
fmt.Println("结果正确", value)
} else {
fmt.Println("错误")
}
}
异常
//异常处理
func adder(a int, b int) (value int, err error) {
if b == 0 {
err = errors.New("除数不能为0")
return
}
value = a / b
return
}
//延迟调用defer
func prin() {
defer fmt.Println("温馨提示1")
fmt.Println("温馨提示2")
fmt.Println("温馨提示3")
}