接口
接口
接口类型 是由一组方法签名定义的集合。
接口类型的变量 可以保存任何实现了这些方法的值 。
注意: 示例代码的 26 行存在一个错误。由于 Abs 方法只为 *Vertex (指针类型)定义,因此 Vertex (值类型)并未实现 Abser 。 Go 语言提供了另外一种数据类型即接口, 它把所有的具有共性的方法定义在一起, 任何其他类型只要实现了这些方法就是实现了这个接口 。
//格式 /* 定义接口 / type interface_name interface { method_name1 [return_type] method_name2 [return_type] method_name3 [return_type] ... method_namen [return_type] } / 定义结构体 / type struct_name struct { / variables / } / 实现接口方法 / func (struct_name_variable struct_name) method_name1() [return_type] { / 方法实现 / } ... func (struct_name_variable struct_name) method_namen() [return_type] { / 方法实现*/ }
23
1 //格式 2 /* 定义接口 */ 3 type
interface_name
interface { 4
method_name1 [ return_type ] 5
method_name2 [ return_type ] 6
method_name3 [ return_type ] 7
... 8
method_namen [ return_type ] 9 } 10 11 /* 定义结构体 */ 12 type
struct_name
struct { 13
/* variables / 14 } 15 16 / 实现接口方法 */ 17 func ( struct_name_variable
struct_name ) method_name1 () [ return_type ] { 18
/* 方法实现 */ 19 } 20 ... 21 func ( struct_name_variable
struct_name ) method_namen () [ return_type ] { 22
/* 方法实现*/ 23 } //一个示例 package main import ( "fmt" ) type Phone interface { call() } type NokiaPhone struct { } func (nokiaPhone NokiaPhone) call() { fmt.Println("I am Nokia, I can call you!") } type IPhone struct { } func (iPhone IPhone) call() { fmt.Println("I am iPhone, I can call you!") } func main() { var phone Phone phone = new(NokiaPhone) phone.call() phone = new(IPhone) phone.call() } //结果 I am Nokia, I can call you! I am iPhone, I can call you!
35
1 //一个示例 2 package
main 3 4 import ( 5
"fmt" 6 ) 7 8 type
Phone
interface { 9
call () 10 } 11 12 type
NokiaPhone
struct { 13 } 14 15 func ( nokiaPhone
NokiaPhone ) call () { 16
fmt . Println ( "I am Nokia, I can call you!" ) 17 } 18 19 type
IPhone
struct { 20 } 21 22 func ( iPhone
IPhone ) call () { 23
fmt . Println ( "I am iPhone, I can call you!" ) 24 } 25 26 func
main () { 27
var
phone
Phone 28 29
phone
=
new ( NokiaPhone ) 30
phone . call () 31 32
phone
=
new ( IPhone ) 33
phone . call () 34 } 35 //结果 36 I
am
Nokia , I
can
call
you ! 37 I
am
iPhone , I
can
call
you ! //复杂一点的示例 package main import ( "fmt" "math" ) type Abser interface {//定义一个接口 该接口需要实现一个 无返回值的Abs() Abs() float64 } func main() { var a Abser//声明接口 f := MyFloat(-math.Sqrt2) v := Vertex001{3, 4} a = f // f实例化了结构体 MyFloat ,而该结构体实现了 Abser a.Abs() fmt.Println("a = f;a.Abs(); ",a.Abs()) a = &v // v实例化了结构体 *Vertex001 ,而该结构体实现了 Abser a.Abs() fmt.Println("a = &v;a.Abs(); ",a.Abs()) // 下面一行,v 是一个 Vertex001(而不是 Vertex001) // 所以没有实现 Abser。 //a = v //错误的示例,因为v是结构体,而结构体是指类型的,并且没有方法在接收值类型的结构体v } type MyFloat float64//实现了这个结构体就可以通过接口调用使用了这个结构体的方法 func (f MyFloat) Abs() float64 {//a = f ; a.Abs;就是在调用这个 if f < 0 { return float64(-f) } return float64(f) } type Vertex001 struct { X, Y float64 } func (v Vertex001) Abs() float64 {//a = &v; a.Abs; 就是在调用这个 return math.Sqrt(v.Xv.X + v.Yv.Y) } //结果 a = f;a.Abs(); 1.4142135623730951 a = &v;a.Abs(); 5
1 //复杂一点的示例 2 package
main 3 4 import ( 5
"fmt" 6
"math" 7 ) 8 9 type
Abser
interface { //定义一个接口 该接口需要实现一个 无返回值的Abs() 10
Abs () float64 11 } 12 13 func
main () { 14
var
a
Abser //声明接口 15
f :
MyFloat (
math . Sqrt2 ) 16
v :
Vertex001 { 3 , 4 } 17 18
a
=
f
// f实例化了结构体 MyFloat ,而该结构体实现了 Abser 19
a . Abs () 20
fmt . Println ( "a = f;a.Abs(); " , a . Abs ()) 21
a
=
& v
// v实例化了结构体 *Vertex001 ,而该结构体实现了 Abser 22
a . Abs () 23
fmt . Println ( "a = &v;a.Abs(); " , a . Abs ()) 24 25
// 下面一行,v 是一个 Vertex001(而不是 *Vertex001) 26
// 所以没有实现 Abser。 27
//a = v //错误的示例,因为v是结构体,而结构体是指类型的,并且没有方法在接收值类型的结构体v 28 } 29 30 type
MyFloat
float64 //实现了这个结构体就可以通过接口调用使用了这个结构体的方法 31 32 func ( f
MyFloat ) Abs () float64 { //a = f ; a.Abs;就是在调用这个 33
if
f
<
0 { 34
return
float64 (
f ) 35
} 36
return
float64 ( f ) 37 } 38 39 type
Vertex001
struct { 40
X , Y
float64 41 } 42 43 func ( v
Vertex001 ) Abs () float64 { //a = &v; a.Abs; 就是在调用这个 44
return
math . Sqrt ( v . X * v . X
v . Y * v . Y ) 45 } 46 47 //结果 48 a
=
f ; a . Abs (); 1.4142135623730951 49 a
=
& v ; a . Abs (); 5