GO面向对象
GO中没有隐藏的this指针
类型系统
类型系统是一个语言的类型体系,GO的类型系统包含以下基本内容:
- 基础类型,如byte、int、bool、float等
- 复合类型,如数组、结构体、指针等
- 可以指向任意对象的类型
- 值语义和引用语义
- 面向对象,即所有具备面向对象特征的类型
- 接口
GO语言的类型系统:
- 给任意类型添加响应的方法
type Integer int
func (a Integer) Less(b Integer) bool {
return a < b
}
- 值语义和引用语义
GO语言中的大多数类型都基于值语义,包括:
- 基本类型,如byte、int、bool、float32、float64和string等;
- 复合类型,如数组、结构体和指针等。
GO中的数组和基本类型没有什么区别,想表达引用时,需要使用指针
var a = [3]int{3,4,5}
var b = &a
几个特殊类型:
- 数组切片:值语义
- map:引用语义
- channel:引用语义
- 接口:具备引用,内部维持了两个指针
type interface struct {
data *void
itab *Itab
}
- 结构体:只支持组合类型
初始化
在GO语言中没有被显示初始化的变量都会被初始化为该类型的零值。
匿名组合
GO语言的继承方式采用的是匿名组合的方式。
type Base struct {
Name string
}
func (base *Base) Foo() { ... }
func (base *Base) Bar() { ... }
type Foo struct {
Base // Base的位置直接与内存布局相关
...
}
// Foo类从Base继承并改写了Bar方法
func (foo *Foo) Bar() {
foo.Base.Bar() //实现时先调用基类Bar()方法
}
此外还有一种继承方式,但是该方式在创建Foo实例的时候需要外部提供一个Base类实例的指针。
type Base struct {
Name string
}
func (base *Base) Foo() { ... }
func (base *Base) Bar() { ... }
type Foo struct {
*Base
...
}
可见性
要使某个符号对其他包可见,需要将该符号定义为大写字母
接口
接口是GO语言整个类型系统的基石,让GO语言在基础编程哲学的探索上达到前所未有的高度。其他语言的接口在使用时都是侵入式的。
GO语言的接口使用是非侵入式的。
type File struct {
...
}
func (f *File) Read(buf []byte) (n int, err error)
func (f *File) Write(buf []byte) (n int, err error)
type IFile interface {
Read(buf []byte) (n int, err error)
Write(buf []byte) (n int, err error)
}
type IReader interface {
Read(buf []byte) (n int, err error)
}
type IWriter interface {
Write(buf []byte) (n int, err error)
}
var file1 IFile = new(File)
var file2 IReader = new(File)
接口赋值在GO语言中分为两种情况:
- 将对象实例赋值给接口
这种方式要求该对象实现了接口要求的所有方法
type Integer int
func (a Integer) Less(b Integer) bool {
return a < b
}
// go 可以自动根据上面的方法生成新的方法
// func (a *Integer) Less(b Integer) bool {
// return a < b
// }
// 但是,不能反过来,因为
func (a *Integer) Add(b Integer) {
*a += b
}
type LessAdder interface {
Less(b Integer) bool
Add(b Integer)
}
// 如果要将Integer对象赋值给接口,只能使用(1),因为*Integer满足LessAdder接口
var a Integer = 1
var b LessAdder = &a // (1)
var b LessAdder = a // (2)
- 将一个接口赋值给另一个接口
接口查询:
var file1 Writer = ...
if file5, ok := file1.(two.IStream); ok {
...
}
var v1 interface{} = ...
switch v := v1.(type) {
case int: //
case string: //
}
接口组合:
type Reader interface {
Read(p []byte) (n int, err error)
}
type Writer interface {
Write(p []byte) (n int, err error)
}
type ReadWriter interface {
Reader
Writer
}
///////等价于
type ReadWriter interface {
Read(p []byte) (n int, err error)
Write(p []byte) (n int, err error)
}
Any类型:interface{}
有疑问加站长微信联系(非本文作者)