Golang入门第四天

  1. 面向对象编程
  2. 匿名字段
  3. 匿名字段初始化
  4. 方法
  5. 值语义与引用语义
  6. 封装,继承,多态
  7. 方法值,方法表达式
  8. 接口
  9. 接口继承,接口转换
  10. 空接口
  11. 通过if实现类型断言
  12. 通过switch实现类型断言
package main

import (
	"fmt"
)

// Out 函数
// interface{} 一个空接口,没有方法,可以保存任何值,所有接口都实现自空接口
func Out(data ...interface{}) {
	// 定义一个切片
	i := make([]interface{}, len(data))
	for j, datum := range data {
		i[j] = datum
	}
	for _, value := range data {
		// value , result := value.(int),".()"判断调用参数是不是参数类型,返回两个参数,value是值,result是判断结果
		if value01, result := value.(int); result == true {
			fmt.Printf("这里是一个int : %v", value01)
		} else {
			switch value.(type) {
			case string:
				fmt.Printf("这里是一个string : %v", value)
			case Student:
				fmt.Printf("这里是一个Student : %v", value)
			default:
				fmt.Printf("未知类型: %T , 值: %v", value)
			}
		}
		fmt.Println(value)
	}
}

// Person 匿名字段
type Person struct {
	name string
	sex  byte
	age  int
}

type Student struct {
	Person
	id   int
	addr string
}

var p Person
var s Student
var s1 Student

// DemoStudentV 值语义方法
func (student Student) DemoStudentV() {
	Out("this is demo student")
}

// DemoStudentP 指针语义方法
func (student *Student) DemoStudentP() {
	Out("this is demo student")
}

// DemoPerson 方法,绑定自定义数据类型的函数叫做方法,被绑定的参数会隐式的作为函数的第一个形参传入
func (person Person) DemoPerson() {
	Out(person, "this is demo person")
}

// Inter 接口
type Inter interface {
	Test()
}

// Inter01 接口的继承
type Inter01 interface {
	Inter
	Test01()
}

// Inter02 接口的继承
type Inter02 interface {
	Inter
	Inter01
	Test02()
}

// Test 实现接口
func (penson Person) Test() {
	Out("person 实现了接口 inter")
}

// Test02 重写方法
func (student Student) Test02() {
	Out("student 实现了接口 inter2")
}

func (student Student) Test03() Student {
	Out("student Test03")
	return student
}

func Anyone(inter Inter) {
	inter.Test()
}

func main() {

	// 多态
	func() {
		// 父子接口转换,超集子集转换
		var i Inter
		// 超集可以转化为子集
		i = p
		i.Test()
		i = s
		i.Test()
		// var i2 Inter02
		// 此处赋值失败,因为s缺少inter02的方法实现test01
		// i2 = s
		// i2.Test01()
		// 多态
		Anyone(i)
		Anyone(p)
		// 方法值,调用函数时,无须再传递参数,隐藏了接收者
		iTest := s.Test03
		// 方法表达式,在调用时决定调用参数
		iTest01 := Student.Test03
		iTest01(s)
		// 等价于i.Test()
		Anyone(iTest())
	}()

	// 结构体初始化
	func() {
		s = Student{
			// 匿名字段初始化
			Person: Person{"xiaoming", 'n', 10},
			id:     0,
			addr:   "",
		}
		s2 := Student{
			Person: Person{},
			id:     0,
			addr:   "",
		}
		Out(s, s2)
		s1 = s2
		// 可用值调用引用语义方法,会自动转化为指针调用
		s.DemoStudentP()
		// 同样可用指针调用值语义方法,会自动转化为值调用
		(&s).DemoStudentV()
	}()

	// 继承
	func() {
		// 方法调用
		p.DemoPerson()
		// 方法继承
		s1.DemoPerson()
		// 调用子集方法
		s1.Person.DemoPerson()
		// p1 是一个指针
		p1 := new(Person)
		fmt.Printf("%T\n", p1)
	}()

}
这里是一个string : person 实现了接口 interperson 实现了接口 inter
这里是一个string : person 实现了接口 interperson 实现了接口 inter
这里是一个string : person 实现了接口 interperson 实现了接口 inter
这里是一个string : person 实现了接口 interperson 实现了接口 inter
这里是一个string : student Test03student Test03
这里是一个string : student Test03student Test03
这里是一个string : person 实现了接口 interperson 实现了接口 inter
这里是一个Student : {{xiaoming 110 10} 0 }{{xiaoming 110 10} 0 }
这里是一个Student : {{ 0 0} 0 }{{ 0 0} 0 }
这里是一个string : this is demo studentthis is demo student
这里是一个string : this is demo studentthis is demo student
未知类型: main.Person , 值: %!v(MISSING){ 0 0}
这里是一个string : this is demo personthis is demo person
未知类型: main.Person , 值: %!v(MISSING){ 0 0}
这里是一个string : this is demo personthis is demo person
未知类型: main.Person , 值: %!v(MISSING){ 0 0}
这里是一个string : this is demo personthis is demo person
*main.Person
posted @ 2023-02-27 23:10  萝卜不会抛异常  阅读(12)  评论(0编辑  收藏  举报