美文网首页
(1)面向对象

(1)面向对象

作者: 爱喝咖啡的土拨鼠 | 来源:发表于2018-01-05 19:06 被阅读0次

    类型系统

    类型系统是指一个语言的类型体系结构。一个典型的类型系统通常包含以下内容:

    • 基础类型:byte int bool ...
    • 复合类型:数组 结构体 指针 ...
    • 可以指向任意对象的类型(Any类型)
    • 值语义和引用语义
    • 面向对象的特征 如成员方法
    • 接口

    类型系统描述的是这些内容在一个语言中如何被关联。

    以java举例,在Java中存在两套完全独立的类型系统:一套是值类型系统,主要是基本数据类型(int byte char 等 ),这些类型是值语义的。另一套则是以Object为根的对象类型,这些类型可以定义成员变量和成员方法。java中的Any类型就是Object,值类型想要被Object引用需要装箱(int->Integer)。

    相比之下Go语言的大多数类型都是值语义,并且都可以包含对应的操作方法。在需要的时候可以给任何类型添加新方法。而在实现某个接口时,无需从该接口继续(Go不支持继承),只要实现该接口要求的所有方法即可。GO语言的Any类型就是空接口interface(),可以引用任何类型。

    为类型添加方法

    例1:

    package main
    
    import "fmt"
    
    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(a,"less 2")
        }
    }
    
    
    运行结果:
    1 less 2
    
    Process finished with exit code 0
    

    例1 定义了一个新类型Integer,我们为其新增了一个Less方法。

    例2:

    package main
    import "fmt"
    type Integer int
    
    func (a *Integer) Add(b Integer) {
        *a += b
    }
    
    func main()  {
        var a Integer =1
        a.Add(2)
        fmt.Println(a)
    }
    

    Go语言中的面向对象最为直观,如果要求对象必须以指针传递,这有时会是个额外成本,有时对象很小,用指针传递并不划算。
    只有在你需要修改对象的时候,才必须使用指针,比如例2
    如果你写成这样

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

    那么你得打的值仍然会是1,而不是3。因为go语言类型都是属于值传递,要想修改变量的值,只能传递指针。

    值语义和引用语义

    值语义和引用语义的差别在于赋值
    b = a
    b.Modify()
    如果b的修改不会影响a,属于值类型,如果影响属于引用类型。

    Go语言中大多数属于值类型,包括:

    • 基本类型 int bool 等
    • 复合类型 array 结构体struct 指针

    Go语言中有4个类型比较特别,看起来像引用类型

    • 数组切片:指向数组的一个区间
    • map:极其常见的数据类型
    • channel:执行体间的通信设施
    • 接口:对一组满足某个契约的类型的抽象
    结构体

    Go 语言的结构体(struct)和其他语言的类(class)有同等地位,但Go放弃了包括继承在内的大量的面向对象的特性,只保留了组合这个最基础的特性。

    定义一个矩形类型,再定义Area成员方法来计算面积

    type Rect struct {
        x, y float64
        width, hight float64
    }
    
    func (rect *Rect)Area() float64 {
        return rect.hight*rect.width
    }
    
    初始化

    定义好了Rect,可以有以下几种方式初始化:

    rect1 := new(Rect)
    rect2 :=&Rect{0,0,100,100}
    rect3 :=&Rect{width:100,hight:100}
    rect4 :=&Rect{}
    

    Go语言没有构函数,使用一个全局的创建函数new来创建

    匿名组合

    确切的说,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类,该类从Base类“继承”并改写了Bar()

    可见性

    Go语言对关键字的增加非常的吝啬,其中没有private、protected、public这样的关键字,要使某个符号对其他包可见,需要定义此符号定义为大写字母

    接口

    接口在Go语言有着至高重要的地位,接口是Go语言整个类型系统的基石,让Go语言在基础编程哲学的探索上达到前所未有的高度。

    非侵入式接口

    在Go语言中,一个类只需要实现了接口所有的函数,我们就说这个类实现了该接口,甚至可以不知道接口的存在,例如以下File类并没有继承IFile IRead IWrite,但是实现了这些接口,所以就可以进行赋值。

    type IFile interface{
      Read (buf []byte) (n int,err error)
      Write(buf []byte)(n int,err error)
      Seek(off int64,whene int)(pos int64,err error)
      Close(err error)
    }
    
    type IRead interface{
     Read (buf []byte) (n int,err error)
    }
    
    type IWrite interface{
        Write (buf []byte) (n int,err error)
    }
    
    type File struct {
    
    }
    func (f *File) Read (buf []byte) (n int,err error){}
    func (f *File) Write(buf []byte)(n int,err error){}
    func (f *File) Seek(off int64,whene int)(pos int64,err error){}
    func (f *File) Close(err error){}
    
    //赋值
    var file1 IFile = new(File)
    var file2 IRead = new(File)
    var file3 IWrite = new(File)
    
    接口赋值

    接口赋值在Go语言中有两种情况:
    将对象实例赋值给接口
    将一个接口赋值给另一个接口

    将某种类型的对象赋值给接口

    type Integer int
    func (a Integer) Less (b Integer)bool{
        return a<b
    }
    
    func (a *Integer) Add (b Integer)bool{
        *a +=b
    }
    
    //定义接口LessAdder
    type LessAdder interface{
        Less (b Integer)bool
        Add (b Integer)
    }
    
    //将对象赋值给接口
    var a Integer = 1
    var b LessAdder =&a  (1)
    var b LessAdder =a   (2)
    
    //其中(1)是正确的赋值是(1)
    

    相关文章

      网友评论

          本文标题:(1)面向对象

          本文链接:https://www.haomeiwen.com/subject/zhwsnxtx.html