golang之多态Interface与成员组合

文章目录


Golang非面向对象的语言:

  • 封装:没有提供public等关键字,而是以大写字符开始来表示包外可见;
  • 继承:没有implements等关键字,而是通过匿名组合(has-a)方式模拟继承;
  • 多态:通过接口(interface)实现的一种duck typing类型

多态

通过Interface可实现多态继承(is-a);可用interface来代表对应的实现类来操作:

type CheckParamValid interface {
	IsValueValid(v float64) bool
	GetKeys() []string
}

func BuildCheckKey(key ...string) []string {
	return key
}
func BuildLowerThreshold(lower float64, key ...string) *LowerCheckParam {
	return &LowerCheckParam{
		Keys:  key,
		Lower: lower,
	}
}
func BuildRangeThreshold(lower float64, upper float64, key ...string) *RangeCheckParam {
	return &RangeCheckParam{
		Keys:  key,
		Lower: lower,
		Upper: upper,
	}
}

type RangeCheckParam struct {
	Keys  []string
	Lower float64
	Upper float64
}

func (this *RangeCheckParam) IsValueValid(v float64) bool {
	return v >= this.Lower && v <= this.Upper
}
func (this *RangeCheckParam) GetKeys() []string {
	return this.Keys
}

type LowerCheckParam struct {
	Keys  []string
	Lower float64
}

func (this *LowerCheckParam) IsValueValid(v float64) bool {
	return v >= this.Lower
}
func (this *LowerCheckParam) GetKeys() []string {
	return this.Keys
}

func ParamCheckTest() {
	thres := map[string][]CheckParamValid{
		"face": []CheckParamValid{
			&RangeCheckParam{BuildCheckKey("box", "width"), 10, 100},
			&LowerCheckParam{BuildCheckKey("Score"), 0.1},
		},
	}

	fmt.Println("To check")
	for _, v := range thres {
		for _, check := range v {
			fmt.Printf("%T check: %v \n", check, check.IsValueValid(5))
		}
	}
}

[]CheckParamValid切片可使用实现此接口的任意类来填充。

继承

go通过组合语法糖实现的继承,即在子类中直接嵌入父类(然后就可以直接访问子类的成员与方法):

  • 多个相同基类时,不能使用匿名组合(只能定义不同的变量)
  • 匿名组合初始化其字段名即为基类名(初始化时,要么全部带字段名,要么全部不带);
  • 组名没有多态能力:如下Calc调用的Add永远是Base的(即使子类中重新定义了Add);若要Calc调用子类的Add,必须在子类中重新实现下Calc函数;
type Base struct {
	Name string
	Count int
}

func (this *Base)Output()string{
	return fmt.Sprintf("name: %v, count: %v", this.Name, this.Count)
}
func (this *Base)Calc() {
	this.Add()
}
func (this *Base)Add(){
	this.Count += 1
}

type Derived struct {
	Base
	Score float32
}
func (this *Derived)Add(){
	this.Count += 10
}


func DeriveTest(){
	b := Base{
		Name: "Base",
		Count: 1,
	}

	d := Derived{
		Base{"Derived",1},
		10,
	}
//	d := Derived{
//		Base:  Base{Name: "explicit"},
//		Score: 0,
//	}
	
	b.Add()
	d.Add() // 调用的Derived的Add
	fmt.Println(b.Output())
	fmt.Println(d.Output())

	b.Calc()
	d.Calc() // 调用的Base的Add
	fmt.Println(b.Output())
	fmt.Println(d.Output())
}

// name: Base, count: 2
// name: Derived, count: 11
// name: Base, count: 3
// name: Derived, count: 12
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值