GoLang之对象

chenny7 · · 9253 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

GoLang之面向对象

 

Go语言没有沿袭传统面向对象编程中的诸多概念,比如继承、虚函数、构造函数和析构函数、隐藏的this指针等。

 

类方法

在Go语言中,可以给任意类型(包括内置类型,但不包括指针类型)添加相应的方法。

如下面的这个例子,定义了一个新类型Integer,它和int一样,只是为它内置的int类型增加了个新方法Less()

type Integer int 

func (a Integer) Less(b Integer) bool {
    return a < b 
}

func main() {
    var a Integer = 1 

    if a.Less(2) {
        fmt.Println("less then 2")
    }   
}

可以看出,Go语言在自定义类型的对象中没有C++/Java那种隐藏的this指针,而是在定义成员方法时显式声明了其所属的对象。

 

如果要修改对象的值,可以传递对象的指针

func (a *Ingeger) Add(b Integer) {
    *a += b
}

func main() {
    var a Integer = 1 
    a.Add(3)
    fmt.Println("a =", a)     //  a = 4
}

如果Add方法不使用指针,则a返回的结果不变,这是因为Go语言函数的参数也是基于值传递。

 

之前说过,Go语言没有构造函数的概念,通常使用一个全局函数来完成。例如:

func NewRect(x, y, width, height float64) *Rect {
    return &Rect{x, y, width, height}
}   

func main() {
    rect1 := NewRect(1,2,10,20)
    fmt.Println(rect1.width)
}

 

 


匿名组合

Go语言提供了继承,但是采用了组合的语法,我们将其称为匿名组合,例如:

type Base struct {
    name string
}

func (base *Base) Set(myname string) {
    base.name = myname
}

func (base *Base) Get() string {
    return base.name
}

type Derived struct {
    Base
    age int 
}

func (derived *Derived) Get() (nm string, ag int) {
    return derived.name, derived.age
}


func main() {
    b := &Derived{}

    b.Set("sina")
    fmt.Println(b.Get())
}

例子中,在Base类型定义了get()和set()两个方法,而Derived类型继承了Base类,并改写了Get()方法,在Derived对象调用Set()方法,会加载基类对应的方法;而调用Get()方法时,加载派生类改写的方法。

 

组合的类型和被组合的类型包含同名成员时, 会不会有问题呢?可以参考下面的例子:

type Base struct {
    name string
    age int
}

func (base *Base) Set(myname string, myage int) {
    base.name = myname
    base.age = myage
}

type Derived struct {
    Base
    name string
}

func main() {
    b := &Derived{}

    b.Set("sina", 30)
    fmt.Println("b.name =",b.name, "\tb.Base.name =", b.Base.name)
    fmt.Println("b.age =",b.age, "\tb.Base.age =", b.Base.age)
}

 

 

 


值语义和引用语义

值语义和引用语义的差别在于赋值,比如

b = a
b.Modify()

如果b的修改不会影响a的值,那么此类型属于值类型;如果会影响a的值,那么此类型是引用类型。

Go语言中的大多数类型都基于值语义,包括:

  • 基本类型,如byte、int、bool、float32、string等;
  • 复合类型,如arry、struct、pointer等;

 

C语言中的数组比较特别,通过函数传递一个数组的时候基于引用语义,但是在结构体定义数组变量的时候基于值语义。而在Go语言中,数组和基本类型没有区别,是很纯粹的值类型,例如:

var a = [3] int{1,2,3}
var b = a
b[1]++
fmt.Println(a, b)   // [1 2 3] [1 3 3]

从结果看,b=a赋值语句是数组内容的完整复制,要想表达引用,需要用指针:

var a = [3] int{1,2,3}
var b = &a    // 引用语义
b[1]++
fmt.Println(a, b)   // [1 3 3] [1 3 3]

 

 


接口

Interface 是一组抽象方法(未具体实现的方法/仅包含方法名参数返回值的方法)的集合,如果实现了 interface 中的所有方法,即该类/对象就实现了该接口。

Interface 格式:

type interfaceName interface {  
    //方法列表  
}  

Interface 可以被任意对象实现,一个类型/对象也可以实现多个 interface;
不支持方法重载;

 

本文来自:博客园

感谢作者:chenny7

查看原文:GoLang之对象

入群交流(和以上内容无关):Go中文网 QQ 交流群:798786647 或加微信入微信群:274768166 备注:入群;关注公众号:Go语言中文网

9253 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传