在 Go 编程中,我们使用接口来存储一组没有实现的方法。也就是说,接口的方法没有方法体。例如,
type Shape interface {
area() float32
perimeter() float32
}
在这里,Shape
是一个接口,它有两个方法:area()
和 perimeter()
。可以看到,这两个方法只有方法签名,没有任何实现。
Go 接口的实现
如果你想知道,如果接口中的方法没有实现,它有什么用。
嗯,要使用接口,我们首先需要用一个类型(struct)来实现它。要实现接口,struct 必须为接口的所有方法提供实现。例如,
package main
import "fmt"
// interface
type Shape interface {
area() float32
}
// struct to implement interface
type Rectangle struct {
length, breadth float32
}
// use struct to implement area() of interface
func (r Rectangle) area() float32 {
return r.length * r.breadth
}
// access method of the interface
func calculate(s Shape) {
fmt.Println("Area:", s.area())
}
// main function
func main() {
// assigns value to struct members
rect := Rectangle{7, 4}
// call calculate() with struct variable rect
calculate(rect)
}
输出
Area: 28
让我们看看这个程序是如何工作的
接口实现工作原理
在上面的例子中,我们创建了一个名为 Shape
的接口,其中有一个方法 area()
。在这里,我们试图用 Rectangle
struct 来实现这个接口。
type Rectangle struct {
length, breadth float32
}
现在,为了实现接口,我们提供了 getArea()
的实现。
func (r Rectangle) area() float32 {
return r.length * r.breadth
}
为了访问这个方法,我们创建了一个 calculate()
方法
// access method of the interface
func calculate(s Shape) {
fmt.Println("Area: ", s.area())
}
在这里,该方法接受一个 Shape
类型的变量,名为 s
,并使用它来调用 area()
方法。
由于该结构实现了接口,我们使用了结构变量调用了 calculate()
rect := Rectangle{7, 4}
calculate(rect)
用多个 Struct 实现 Go 接口
在 Go 中,一个接口也可以被多个 struct 实现。例如,
package main
import "fmt"
// interface
type Shape interface {
area() float32
}
// Rectangle struct implements the interface
type Rectangle struct {
length, breadth float32
}
// Rectangle provides implementation for area()
func (r Rectangle) area() float32 {
return r.length * r.breadth
}
// Triangle struct implements the interface
type Triangle struct {
base, height float32
}
// Triangle provides implementation for area()
func (t Triangle) area() float32 {
return 0.5 * t.base * t.height
}
// access method of the interface
func calculate(s Shape) float32 {
return s.area()
}
// main function
func main() {
// assigns value to struct members
r := Rectangle{7, 4}
t := Triangle{8, 12}
// call calculate() with struct variable rect
rectangleArea := calculate(r)
fmt.Println("Area of Rectangle:", rectangleArea)
triangleArea := calculate(t)
fmt.Println("Area of Triangle:", triangleArea)
}
输出
Area of Rectangle: 28 Area of Rectangle: 48
在上面的例子中,我们使用了两个 struct:Rectangle
和 Triangle
来实现 Shape
接口。
和以前一样,这两个 struct 都为 area()
方法提供了实现。
这次,calculate()
使用接口 Shape
调用 area()
并返回它。
所以,对于第一个调用 calculate(r)
,该方法将调用 Rectangle
的 area()
方法实现。同样,对于 calculate(t)
,该方法将调用 Triangle
的 area()
方法实现。
如果 struct 没有实现接口的所有方法会怎样?
当一个 struct 实现一个接口时,它应该为接口的所有方法提供实现。如果它未能实现任何方法,我们将收到一个错误。例如,
package main
import "fmt"
// interface
type Shape interface {
area() float32
perimeter() float32
}
// Rectangle struct implements the interface
type Rectangle struct {
length, breadth float32
}
// Rectangle provides implementation for area()
func (r Rectangle) area() float32 {
return r.length * r.breadth
}
// access method of the interface
func calculate(s Shape) float32 {
return s.area()
}
// main function
func main() {
// assigns value to struct members
r := Rectangle{7, 4}
// call calculate() with struct variable rect
rectangleArea := calculate(r)
fmt.Println("Area of Rectangle:", rectangleArea)
}
输出
cannot use r (type Rectangle) as type Shape in argument to calculate: Rectangle does not implement Shape (missing perimeter method)
在上面的例子中,Shape
接口有两个方法:area()
和 perimeter()
。在这里,我们试图用 Rectangle
struct 来实现接口。
但是,该 struct 只提供了 area()
的实现。由于该 struct 没有实现接口的所有方法,因此我们得到了一个错误。