第11章 1.接口定义

2020-01-18  本文已影响0人  yezide

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)
上一篇 下一篇

猜你喜欢

热点阅读