Golang interface接口
一.interface接口
1 package student 2 3 import ( 4 "fmt" 5 ) 6 7 /* 8 接口: 9 10 1.接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量 11 2.接口中所有的方法都没有方法体,即没有实现方法 12 3.必须将接口的所有方法实现,才算实现了该接口. 13 4.实现了接口的结构体变量,才能将该变量赋值给接口 14 5.只要是数据类型都可以实现接口(不仅仅是结构体类型) 15 6.一个类型可以实现多个接口 16 7.Golang接口中不像Java C++的接口..Golang接口中只能有未实现的方法,不能定义变量或常量... 17 8.一个接口可以继承其他一个或多个接口.但其他继承来的接口方法不允许重名,不然编译报错 18 9.interface类型变量,默认是一个指针,如果没有初始化的话就是nil 19 */ 20 type Stu struct { 21 Name string 22 } 23 24 type Test interface { 25 Test() bool 26 Test1() bool 27 } 28 29 type Say interface { 30 Say() 31 } 32 33 type Hello interface { 34 Print1() 35 Say() 36 } 37 38 func (self *Stu) Test() bool { 39 self.Name = "Tom" 40 fmt.Println(self.Name, "考试通过!") 41 return true 42 } 43 44 func (self Stu) Test1() bool { // 这里的self接受器必须和Test()中的一致.如果不一致接口赋值初始化的时候必须用变量地址去赋值 45 46 fmt.Println(self.Name, "考试通过1!") 47 return true 48 } 49 50 func (self Stu) Say() { 51 fmt.Println("Hello ", self.Name) 52 } 53 54 func (self Stu) Print1() { 55 fmt.Println("Print1") 56 } 57 58 // 将接口变量还原成 原类型变量 59 func TestType() { 60 stu := Stu{"Mary"} 61 var t1 Test = &stu // Test是接口 62 // 如果你需要将接口变量,转换原来的类型 63 var s2 *Stu = t1.(*Stu) // 这里如果报错的话就会断言终止程序 64 fmt.Println(s2.Name) 65 // 另外一种转回原来变量 66 if s3, ok := t1.(*Stu); ok { 67 fmt.Printf("s3的类型是:%T, s3的值是:%v \n", *s3, *s3) 68 fmt.Println("convert 成功!") 69 } else { 70 fmt.Println("convert 失败!") 71 } 72 } 73 74 // 主动获取接口类型 75 func TestGetInterfaceObj(items ...interface{}) { 76 for index, obj := range items { 77 index++ 78 switch obj.(type) { 79 case int: 80 fmt.Printf("第%v个参数是 int, 值是:%v \n", index, obj) 81 case float64: 82 fmt.Printf("第%v个参数是 float64, 值是:%v \n", index, obj) 83 case Stu, *Stu: 84 fmt.Printf("第%v个参数是 Stu, 值是:%v \n", index, obj) 85 default: 86 fmt.Printf("第%v个参数是 未知, 值是:%v \n", index, obj) 87 88 } 89 } 90 } 91 92 func TestInterface() { 93 94 stu := Stu{"Mary"} 95 var t1 Test = &stu // 注意!! Test实现的时候用的结构体指针,所以需要用地址去赋值调用 96 var s1 Say = stu 97 var h1 Hello = &stu // 只要实现了接口中的方法就能使用. Say()是Hello接口和Say接口都需要实现的方法 98 t1.Test() 99 t1.Test1() 100 s1.Say() 101 h1.Print1() 102 TestType() 103 var i1 int = 10 104 var f1 float64 = 1.1 105 TestGetInterfaceObj(i1, s1, f1, t1) 106 }
二.利用接口实现堆排序
1 package student 2 3 import ( 4 "fmt" 5 "math/rand" 6 ) 7 8 type StuSlice []student 9 10 type SortData interface { 11 Less(i, j int) bool 12 } 13 14 // 堆排序:二叉树,大小堆.步骤:1.建堆 2.堆顶与堆尾交换固定堆尾 3.继续重复做建堆 15 16 func heapify(arr1 StuSlice, n int, i int) { 17 maxIndex := n - 1 18 c1 := (i * 2) + 1 19 c2 := c1 + 1 20 if c1 > maxIndex { 21 return 22 } 23 24 // if arr1[i] < arr1[c1] { 25 if arr1.Less(i, c1) { 26 // tem := arr1[i] 27 // arr1[i] = arr1[c1] 28 // arr1[c1] = tem 29 arr1[i], arr1[c1] = arr1[c1], arr1[i] 30 heapify(arr1, n, c1) 31 } 32 // if (c2 <= maxIndex) && (arr1[i] < arr1[c2]) { 33 if (c2 <= maxIndex) && arr1.Less(i, c2) { 34 // tem := arr1[i] 35 // arr1[i] = arr1[c2] 36 // arr1[c2] = tem 37 arr1[i], arr1[c2] = arr1[c2], arr1[i] 38 heapify(arr1, n, c1) 39 } 40 41 } 42 func buildHeap(arr1 StuSlice) { 43 if len(arr1) < 2 { 44 return 45 } 46 maxIndex := len(arr1) - 1 47 heapIndex := (maxIndex - 1) / 2 48 49 for i := heapIndex; i >= 0; i-- { 50 heapify(arr1, len(arr1), i) 51 } 52 } 53 func HeapSort(arr1 StuSlice) { 54 buildHeap(arr1) 55 // fmt.Println("buildHeap=", arr1) 56 for i := len(arr1) - 1; i > 0; i-- { 57 58 arr1[i], arr1[0] = arr1[0], arr1[i] 59 // tem := arr1[i] 60 // arr1[i] = arr1[0] 61 // arr1[0] = tem 62 heapify(arr1, i, 0) 63 } 64 // fmt.Println("buildHeap=", arr1) 65 } 66 67 func (self *StuSlice) Less(i, j int) bool { 68 return ((*self)[i].Age > (*self)[j].Age) 69 } 70 71 func TestSort() { 72 var arr StuSlice = make([]student, 10) 73 for i := 0; i < len(arr); i++ { 74 arr[i].score = int16(rand.Intn(10)) 75 arr[i].Age = int8(rand.Intn(100)) 76 arr[i].ClassID = "七年级(3)班" 77 arr[i].Name = fmt.Sprintf("Jerry%v", i) 78 } 79 HeapSort(arr) 80 for i := 0; i < len(arr); i++ { 81 fmt.Println(arr[i]) 82 } 83 84 }