go 的无数据抽象设计

786 阅读2分钟
原文链接: kuanshijiao.com
go

interface是golang的抽象设计的根基,是方法集合的接口,是一个非常强大的并且规范的指针,可以引用任意实现了该接口的方法集合的struct,不能定义属性,意味着在抽象设计里是不允许有数据的,使语言的编译运行管理更纯粹方便。

一切属性都是setter/getter

package main
type Surface struct{
    skin string
}
func (s *Surface) Skin() string{
    return "My skin is " + s.skin
}
type Men interface {
    GetSurface() Surface
}
type European struct {
    surface Surface
}
func (p *European) GetSurface() Surface{
    return p.surface
}
type African struct {
    surface Surface
}
func (p *African) GetSurface() Surface{
    return p.surface
}
func Introduce(men Men){
    s := men.GetSurface()
    println(s.Skin())
}
func main() {
    var s Surface
    s = Surface{"white"}
    e := European{s}
    Introduce(&e)
    s = Surface{"black"}
    a := African{s}
    Introduce(&a)
}

上例中的多态,通过setter/getter变相完成了property在interface定义,用方法多态来实现属性多态。

父类方法A调用子类方法B

package main
type Men interface {
    Age() int
}
type Parent struct {
    Men //隐式
    m Men //显式
}
func (p *Parent) Age() int{
    return 80
}
func (p *Parent) Display1() {
    println(p.Men.Age())
}
func (p *Parent) Display2() {
    println(p.m.Age())
}
type Child struct {
    Parent
}
func (c *Child) Age() int{
    return 40
}
func main() {
    var child *Child
    var parent *Parent
    parent = &Parent{parent, nil}
    child = &Child{Parent: *parent}
    println("====parent")
    child.Display1()
    parent = &Parent{child, nil}
    child = &Child{Parent: *parent}
    println("====child")
    child.Display1()
    child.m = parent
    println("====parent")
    child.Display2()
    child.m = child
    println("====child")
    child.Display2()
}

上例中的实现了在父类的A方法中调用父类或者子类的B方法,类似于抽象方法。因为go是静态语言,没有动态语言强大的查找机制,也没有虚函数(virtural method)和抽象方法(abstract method)之类的辅助高级别的多态。

幸好,golang有指针,即interface,又名接口,通过在父类定义接口类型的属性,并在实例化的时候动态绑定该属性的真正类型,来完成父类方法中一些多态方法的灵活调用,增加了公共部分的复用性。

贝叶斯断癌 >