go基本语法学习笔记之面向对象

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

类型系统

GO中大多数类型都是值语义的,并且都可以包含对应的操作方法,而且可以在需要时给类型添加新方法。
在实现某个接口时,无需从该接口继承(事实上GO根本就不支持面向对象中的集成语法),只需实现该接口所要求的所有方法即可。
任何类型都可以被Any类型引用。Any类型就是空接口,即interface{}。

为类型添加方法

可以给任意类型添加方法
type Integer int
func (a Integer) Less(b Integer) bool {
     return a < b
}

var a Integer = 1
if a.Less(2) {
      fmt.Println(a, "Less 2")
}
“在Go语言中没有隐藏的this指针”这句话的含义是:
方法施加的目标(也就是“对象”)显式传递,没有被隐藏起来;
方法施加的目标(也就是“对象”)不需要非得是指针,也不用非得叫this。

值语义和引用语义

二者差别在于:赋值
b = a
b.Modify()
b的修改不会影响a,则是值语义,否则为引用语义
b = &a
b.Modify()
Go语言中的大多数类型都基于值语义,包括:
基本类型,如byte、int、bool、float32、float64和string等;
复合类型,如数组(array)、结构体(struct)和指针(pointer)等。
Go语言中有4个类型比较特别,看起来像引用类型,如下所示:
数组切片:指向数组(array)的一个区间。
map:极其常见的数据结构,提供键值查询能力。
channel:执行体(goroutine)间的通信设施。
接口(interface):对一组满足某个契约的类型的抽象

channel和map类似,本质上是一个指针

结构体

Go语言的结构体(struct)和其他语言的类(class)有同等的地位,但Go语言放弃了包括继承在内的大量面向对象特性,只保留了组合
(composition)这个最基础的特性。
type Rect struct {
      x, y float64 
      width, height float64
}
//定义方法
func (r *Rect) Area() float64 {
       return r.width * r.height
}
看上去很像C吧,事实也如此,的使用方式与C语言并没有明显不同

初始化
rect1 := new(Rect)
rect2 := &Rect{}
rect3 := &Rect{0, 0, 100, 200}
rect4 := &Rect{width: 100, height: 200}
未进行显式初始化的变量都会被初始化为该类型的零值:bool ->false  int->0 string ->空字符串
在Go语言中没有构造函数的概念,对象的创建通常交由一个全局的创建函数来完成,以
NewXXX来命名,表示“构造函数”:
func NewRect(x, y, width, height float64) *Rect {
        return &Rect{x, y, width, height}
}

匿名组合

确切地说,Go语言也提供了继承,但是采用了组合的文法,所以我们将其称为匿名组合:
type Base struct {
    Name string
}
func (base *Base) Foo() { ... }
func (base *Base) Bar() { ... }
type Foo struct {
    Base
    ...
}
func (foo *Foo) Bar() {
   foo.Base.Bar()
    ...
}
以上,定义了Base类,实现了Foo和Bar方法, 定义Foo类,继承并改写了Bar,没有改下Foo也就被继承了
在Go语言中,你还可以以指针方式从一个类型“派生”:
type Foo struct {
     *Base
     ...
}
关注一下接口组合中的名字冲突问题
type X struct {
     Name string
}
type Y struct {
    X
    Name string
}
如上例,Y类型中有有成员Name,其匿名组合X中也有同名的Name,但所有Y类型访问成员Name都只能访问到外层的,X类中的Name被隐藏了
再看:
type Logger struct {
    Level int
}
type Y struct {
    *Logger
    Name string
    *log.Logger
}
如上就不行了,匿名组合,可以认为是用其类型名称(去掉包名部分)作为成员变量的名字,这里就会有两个同名的 Logger。那是不可以










有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:wolgame

查看原文:go基本语法学习笔记之面向对象

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

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