简单地说,接口就是一组方法签名的组合。我们使用一个接口来识别一个对象能够进行的操作。一个接口可以被任意数量的类型满足,而且一个类型可以实现任意数量的接口。每个类型都实现了一个空接口interface{}。

    如果你声明了一个接口变量,这个变量能够存储任何实现该接口的对象类型。

    1. package main
    2. import "fmt"
    3. type Human struct {
    4. name string
    5. age int
    6. phone string
    7. }
    8. type Student struct {
    9. Human //an anonymous field of type Human
    10. school string
    11. loan float32
    12. }
    13. type Employee struct {
    14. Human //an anonymous field of type Human
    15. company string
    16. money float32
    17. }
    18. //A human method to say hi
    19. func (h Human) SayHi() {
    20. fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
    21. }
    22. //A human can sing a song
    23. func (h Human) Sing(lyrics string) {
    24. fmt.Println("La la la la...", lyrics)
    25. }
    26. //Employee's method overrides Human's one
    27. func (e Employee) SayHi() {
    28. fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,
    29. e.company, e.phone) //Yes you can split into 2 lines here.
    30. }
    31. // Interface Men is implemented by Human, Student and Employee
    32. // because it contains methods implemented by them.
    33. type Men interface {
    34. SayHi()
    35. Sing(lyrics string)
    36. }
    37. func main() {
    38. mike := Student{Human{"Mike", 25, "222-222-XXX"}, "MIT", 0.00}
    39. paul := Student{Human{"Paul", 26, "111-222-XXX"}, "Harvard", 100}
    40. sam := Employee{Human{"Sam", 36, "444-222-XXX"}, "Golang Inc.", 1000}
    41. Tom := Employee{Human{"Sam", 36, "444-222-XXX"}, "Things Ltd.", 5000}
    42. //a variable of the interface type Men
    43. var i Men
    44. //i can store a Student
    45. i = mike
    46. fmt.Println("This is Mike, a Student:")
    47. i.SayHi()
    48. i.Sing("November rain")
    49. //i can store an Employee too
    50. i = Tom
    51. fmt.Println("This is Tom, an Employee:")
    52. i.SayHi()
    53. i.Sing("Born to be wild")
    54. //a slice of Men
    55. fmt.Println("Let's use a slice of Men and see what happens")
    56. x := make([]Men, 3)
    57. //These elements are of different types that satisfy the Men interface
    58. x[0], x[1], x[2] = paul, sam, mike
    59. for _, value := range x {
    60. value.SayHi()
    61. }
    62. }

    输出是:

    1. This is Mike, a Student:
    2. Hi, I am Mike you can call me on 222-222-XXX
    3. La la la la... November rain
    4. This is Tom, an Employee:
    5. Hi, I am Sam, I work at Things Ltd.. Call me on 444-222-XXX
    6. La la la la... Born to be wild
    7. Lets use a slice of Men and see what happens
    8. Hi, I am Paul you can call me on 111-222-XXX
    9. Hi, I am Sam, I work at Golang Inc.. Call me on 444-222-XXX
    10. Hi, I am Mike you can call me on 222-222-XXX

    从上面的代码可以看出,接口类型是一组抽象的方法集,它本身不实现方法或者精确描述数据结构和方法的实现方式。接口本身并不关心到底是什么数据类型实现了它。接口类型的本质就是如果一个数据类型实现了自身的方法集,那么该接口类型变量就能够引用该数据类型的值。

    1. 空接口类型interface{}一个方法签名也不包含,所以所有的数据类型都实现了该方法。

    空接口类型在描述一个对象实例的形式上力不从心,但是当我们需要存储任意数据类型的实例的时候,空接口类型的使用使得我们得心应手。


    Go 接口 - 图1