百无一用程序员

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

接口与反射

接口

定义

接口定义了一组方法(方法集),但是这些方法不包含(实现)代码,接口里也不能包含变量。

通过如下格式定义接口:

type InterfaceName interface {
    Method1(param_list) return_type
    Method2(param_list) return_type
    ...
}

范例,将形状的面积方法抽取出来作为抽象接口:

type Shaper interface {
	Area() float64
}

type Square struct {
	side float64
}

func (s *Square) Area() float64 {	// 实现抽象接口
	return s.side*s.side
}

调用:

    sq1 := new(Square)
    sq1.side = 10

    var shp Shaper = sq1	// 获取结构体对应的抽象接口
    fmt.Printf("\t正方形边长: %f,面积: %f\n", sq1.side, shp.Area())

上面的代码中var shp Shaper = sq1实现了从结构体到接口类型的转化,shp中保存了对该对象的引用,使用这种方式就可以实现面向对象的多态。

将结构体转化成接口的前提是:该结构体实现了接口中所有的方法

判断接口持有者的类型(向下转换)

在使用面向对象语言时,经常需要判断持有抽象接口的对象类型,这样就可以进行向下转换,Go语言提供了同样的功能:

v, ok := varIntf.(T);	// T表示被绑定的类型

通过上述接口,可以判断该接口绑定的对象类型,例如判断一个Shaper接口是不是Square

if v,ret := shp.(*Square); ret {
	fmt.Printf("\t该Shaper接口绑定的是Square类型:%v\n", v);
}

这里与可以使用switch的type来判定:

switch t := shp.(type) {
	case *Square:
		fmt.Printf("\tType Square %T with value %v\n", t, t)
	default:
		fmt.Printf("\tUnexpected type %T\n", t)
}

空接口

任何其他类型都实现了空接口(它不仅仅像 Java/C# 中 Object 引用类型),any 或 Any 是空接口一个很好的别名或缩写。

空接口类似 Java/C# 中所有类的基类: Object 类,二者的目标也很相近。可以给一个空接口类型的变量 var val interface {} 赋任何类型的值。

空接口定义范例:

type Any interface{}
posted on 2021-02-28 20:20  psbec  阅读(77)  评论(0编辑  收藏  举报