1、初识接口
package main
import "fmt"
// 定义接口
type IShaper interface {
Area() float32
}
// 接口实现
type Shaper struct {
side float32
}
// 实现接口方法
// 如果没有实现这个方法, 编译时就会报错误:
//./test.go:28:9: cannot use sqObj (type *Shaper) as type IShaper in assignment:
// *Shaper does not implement IShaper (missing Area method)
func (sq *Shaper) Area() float32 {
return sq.side * sq.side
}
func main() {
// 关键来了
// 先定义实现类
sqObj := new(Shaper)
sqObj.side = 3.3
// 定义接口
var isIntf IShaper
// 绑定它
isIntf = sqObj;
// 以上相当于java的
// IShaper isIntf = new Shaper()
// isIntf.Area()
fmt.Printf("The square has area: %f\n", isIntf.Area())
}
2、 直接定义接口实例
package main
import "fmt"
type StockPosition struct {
ticker string
sharePrice float32
count float32
}
func (s StockPosition) getValue() float32 {
return s.sharePrice * s.count
}
type Car struct {
make string
model string
price float32
}
func (c Car) getValue() float32 {
return c.price
}
type IValuable interface {
getValue() float32
}
// 这个方法的入参数是个接口类型
func showValue(v IValuable) {
fmt.Printf("Value of the asset is %f\n", v.getValue())
}
func main() {
var obj1 IValuable = StockPosition{"test1", 1.1, 2.2}
// 传入stockPosition的实例
showValue(obj1);
// 传入Car的实例
var obj2 IValuable = Car{"bmw", "3xi", 4.4}
showValue(obj2)
}
3、 判断类型,相当于typeof
package main
import "fmt"
import "math"
type Square struct {
side float32
}
type Circle struct {
radius float32
}
type IShaper interface {
Area() float32
}
func (sq *Square) Area() float32 {
return sq.side * sq.side
}
func (ci *Circle) Area() float32 {
return ci.radius * ci.radius * math.Pi
}
func main() {
var intf1 IShaper
sq1 := new(Square)
sq1.side = 2.1
intf1 = sq1
// 判断intf1属于Square的实例
t, ok := intf1.(*Square)
if ok {
fmt.Printf("The type of areaIntf is: %T\n", t)
}
}
package main
import "fmt"
import "math"
type Square struct {
side float32
}
type Circle struct {
radius float32
}
type IShaper interface {
Area() float32
}
func (sq *Square) Area() float32 {
return sq.side * sq.side
}
func (ci *Circle) Area() float32 {
return ci.radius * ci.radius * math.Pi
}
func main() {
var intf1 IShaper
sq1 := new(Square)
sq1.side = 2.1
intf1 = sq1
// 用switch语法
switch t := intf1.(type) {
case *Square1:
fmt.Printf("Type Square %T with value %v\n", t, t)
}
}
4、方法集调用规则
Go 语言规范定义了接口方法集的调用规则:
类型 *T 的可调用方法集包含接受者为 *T 或 T 的所有方法集
类型 T 的可调用方法集包含接受者为 T 的所有方法
类型 T 的可调用方法集不包含接受者为 *T 的方法
// 这就可以解释了刚才那例为什么用会编译报错了
// 再补充下,接口变量中存储的具体值是不可寻址的
var intf2 IShaper = Square{1.1}
//./test.go:40:6: cannot use Square literal (type Square) as type IShaper in assignment:
//Square does not implement IShaper (Area method has pointer receiver)
网友评论