Golang初级系列教程-接口

Golang初级系列教程-接口

接口是方法定义和实现之间的准则。在现实生活中,我们无形中就遵循某些接口或者是我们希望他人遵循的。当我们进入银行存钱时,我们希望银行能够帮我们安全的管理钱财并且提供额外的收益;但是我们并不关心银行如何去运作。这种隐性契约就是我们和银行之间的交互接口。

在编程语言中,接口都遵循同一种模式。下面我们会使用一种不同于 C++JavaC# 等等面向对象语言的接口模式来列举几个 Go 语言的例子。Go 作为一种面向过程的语言,它的接口设计也非常好,并且能够产出很多优秀的设计。

在例子中,我们会求取各种图形,例如长方形、正常性、圆形等等的面积。我们把 Shage 作为一种接口,定义求取面积的方法,实际图形 RectangleSquareCircle 等等实现各自的求取面积的具体方法。至此,我们可以通过同一种调用方式,获得各种图形的面积。

如果是程序小白,可能对接口的概念还不是太熟悉,但是慢慢你会发现,接口是非常有用的设计方式。比如在现实生活中,每个医院都遵循一样的工作方式,挂号-看病-交钱-取药,我们只需要掌握这一种工作流程,去每一所医院,都不会搞的晕头转向。

让我们一步一步来,首先,创建一个 Rectangle,并且打印其面积

package main

import "fmt"

//define a Rectangle struct that has a length and a width
type Rectangle struct {
   length, width int
}

//write a function Area that can apply to a Rectangle type
func (r Rectangle) Area() int {
   return r.length * r.width
}

func main() {
   r := Rectangle{length:5, width:3} //define a new Rectangle instance with values for its properties
   fmt.Println("Rectangle details are: ",r)  
   fmt.Println("Rectangle's area is: ", r.Area())
}
Rectangle details are: {5 3}
Rectangle's area is: 15

就如同前面的代码一样,上述的代码中没有接口,让我们把 Area() 拿出来,放入接口 Shaper 当中。

Go 中通过在命名之后添加 er 以表征这是一个接口,当然其它定义也是可能,这样只是大家遵循的一种编程命名方式,可以使代码更易读。

package main

import "fmt"

//Shaper is an interface and has a single function Area that returns an int.
type Shaper interface {
   Area() int
}

type Rectangle struct {
   length, width int
}

//this function Area works on the type Rectangle and has the same function signature defined in the interface Shaper.  Therefore, Rectangle now implements the interface Shaper.
func (r Rectangle) Area() int {
   return r.length * r.width
}

func main() {
   r := Rectangle{length:5, width:3}
   fmt.Println("Rectangle r details are: ", r)  
   fmt.Println("Rectangle r's area is: ", r.Area())  

   s := Shaper(r)
   fmt.Println("Area of the Shape r is: ", s.Area())  

}
Rectangle r details are: {5 3}
Rectangle r's area is: 15
Area of the Shape r is: 15

C++ 或者 Java 中继承接口时,需要明确的声明这一关系,例如上面的代码,用 Java 来写的话,可能为如下的语句

public class Rectangle implements Shaper { //implementation here }

Go 中,无需表现出这层关系。上面代码中,接口 Shaper 定义一个方式 Area() int。而 Rectangle 也定义了一个相同的方法 func (r Rectangle) Area() int。所以, Go 会认为 Rectangle 实现了 Shaper 的接口。所以,我们可以定义 RectangleShaper 类型:r := Shaper(r) ,之后调用 Area() 方法,输出 Rectangle 的面积。

让我们继续添加 Square 也实现 Area() int , 来看一看如何通过接口统一的访问每种类型的面积。

package main

import "fmt"

type Shaper interface {
   Area() int
}

type Rectangle struct {
   length, width int
}

func (r Rectangle) Area() int {
   return r.length * r.width
}

type Square struct {
   side int
}

//the Square type also has an Area function and therefore, it too, implements the Shaper interface
func (sq Square) Area() int {
   return sq.side * sq.side
}

func main() {
   r := Rectangle{length:5, width:3}
   fmt.Println("Rectangle details are: ",r)  

   var s Shaper
   s = r //equivalent to "s = Shaper(r)" since Go identifies r matches the Shaper interface
   fmt.Println("Area of Shaper(Rectangle): ", s.Area())
   fmt.Println()

   q := Square{side:5}
   fmt.Println("Square details are: ",q)  
   s = q //equivalent to "s = Shaper(q)
   fmt.Println("Area of Shaper(Square): ", s.Area())
   fmt.Println()
}
Rectangle details are: {5 3}
Area of Shaper(Rectangle): 15

Square details are: {5}
Area of Shaper(Square): 25

当前我们按照 Rectange 的方式实现了另一个类型 Square。 让我们通过循环的方式,更加准确的说明一下接口的用途。在下面的代码中,创建 Shaper 实例的列表,通过循环输出每种具体类型的面积。

package main

import "fmt"

type Shaper interface {
   Area() int
}

type Rectangle struct {
   length, width int
}

func (r Rectangle) Area() int {
   return r.length * r.width
}

type Square struct {
   side int
}

func (sq Square) Area() int {
   return sq.side * sq.side
}

func main() {
   r := Rectangle{length:5, width:3}
   q := Square{side:5}
   shapesArr := [...]Shaper{r, q}

   fmt.Println("Looping through shapes for area ...")
   for n, _ := range shapesArr {
       fmt.Println("Shape details: ", shapesArr[n])
       fmt.Println("Area of this shape is: ", shapesArr[n].Area())
   }
}
Looping through shapes for area ...
Shape details: {5 3}
Area of this shape is: 15
Shape details: {5}
Area of this shape is: 25

译者注:关于 Go interface 的设 计方式,如果大家觉得很新颖,可以看看这篇文章 Duck Typing


Golang一种神奇的语言,让我们一起进步

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值