Interface接口

  这一章我们要讲解一下Go的另外一个重要类型——接口类型。

  Go 语言不是一种 “传统” 的面向对象编程语言:它里面没有类和继承的概念。但是 Go 语言里有非常灵活的接口概念,通过它可以实现很多面向对象的特性。

接口定义

普通定义形式:

  1. type Interface Shape{ //最普通的形式
  2. Area() float64
  3. }

空接口定义:

空接口,即 interface{},可以代表任何类型,有点类似于 java 中的 Object 类可以作为任何形参和返回类型。

  1. func test( i int ) interface{} {
  2. if i == 0 {
  3. return "hello"
  4. }
  5. return i;
  6. }

这里例子中,由于有可能返回string,也有可能返回int,因此将返回值设置成为interface,这个在Go的package包中会大量见到。

类型不需要显式声明它实现了某个接口:接口被隐式地实现,多个类型可以实现同一个接口。只要类型实现了接口中的方法,它就实现了此接口。

pro03_8_1.go

  1. //接口定义
  2. type Shape interface {
  3. Area() float64 //求面积
  4. }
  5. //圆形定义
  6. type Circle struct {
  7. radius float64
  8. }
  9. //圆形面积计算
  10. func (this Circle) Area() float64 {
  11. return math.Pi * this.radius * this.radius
  12. }
  13. //矩形定义
  14. type Rectangle struct {
  15. length float64
  16. width float64
  17. }
  18. //矩形面积计算
  19. func (this Rectangle) Area() float64 {
  20. return this.length * this.width
  21. }
  22. func main() {
  23. var circle Circle
  24. circle.radius = 3
  25. fmt.Println(circle.Area())
  26. rec := Rectangle{5.0, 8}
  27. fmt.Println(rec.Area())
  28. }

接口嵌套接口

接口可以包含其他接口.

  1. type ShapeArea interface {
  2. Area() float64 //求面积
  3. }
  4. type ShapePerimeter interface{
  5. Perimeter() float64 // 求周长
  6. }
  7. type Shape interface{
  8. ShapeArea
  9. ShapePerimeter
  10. }

详细情况看pro03_8_2.go

  1. //面积接口
  2. type ShapeArea interface {
  3. Area() float64 //求面积
  4. }
  5. //周长接口
  6. type ShapePerimeter interface {
  7. Perimeter() float64 // 求周长
  8. }
  9. //形状接口:包含面积接口、周长接口
  10. type Shape interface {
  11. ShapeArea
  12. ShapePerimeter
  13. }
  14. //圆形定义
  15. type Circle struct {
  16. radius float64
  17. }
  18. //实现圆形面积接口
  19. func (this Circle) Area() float64 {
  20. return math.Pi * this.radius * this.radius
  21. }
  22. //实现圆形周长接口
  23. func (this Circle) Perimeter() float64 {
  24. return 2 * math.Pi * this.radius
  25. }
  26. func main() {
  27. var circle Circle
  28. circle.radius = 3
  29. fmt.Println("Cirle area:", circle.Area())
  30. fmt.Println("Cirle perimeter:", circle.Perimeter())
  31. }

检测对象是否实现了接口的方法

  1. var circle Circle
  2. circle.radius = 3
  3. var s Shape = circle
  4. if circleValue, ok := s.(ShapePerimeter); ok {
  5. fmt.Printf("circle implements Perimeter(): %f\n", circleValue.Perimeter())
  6. }

通过上面的例子,我们可以看出Shape接口实现了ShapePerimeter接口