go语言的面向对象

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

前言:

go语言的类型系统

 基础类型,如byte、int、bool、float等;

 复合类型,如数组、结构体、指针等;
 可以指向任意对象的类型(Any类型);
 值语义和引用语义;
 面向对象,即所有具备面向对象特征(比如成员方法)的类型;

 接口。


Go语言和C语言一样,类型都是基于值传递的,如果想要引用该值,则引用即可,减少了使用指针的空间浪费;

                                                                              如果想要修改该值,则需要传递指针。

Java中存在两套完全独立的类型系统:
一套是值类型系统,主要是基本类型, 如byte、int、boolean、char、double等,这些类型基于值语义;

一套是以Object类型为根的对象类型系统,这些类型可以定义成员变量和成员方法,可以有虚函数,基于引用语义,只允许在堆上创建(通过使用关键字new)

Java语言中的Any类型就是整个对象类型系统的根——java.lang.Object类型,只有对象类型系统中的实例才可以被Any类型引用。

值类型想要被Any类型引用,需要装箱(boxing)过程,比如int类型需要装箱成为Integer类型。

另外,只有对象类型系统中的类型才可以实现接口,具体方法是让该类型从要实现的接口继承


Go语言中的大多数类型都是值语义,并且都可以包含对应的操作方法。

任何类型都可以被Any类型引用。Any类型就是空接口, 即interface{}

而在实现某个接口时,无需从该接口继承(事实上,Go语言根本就不支持面向对象思想中的继承语法),只需要实现该接口要求的所有方法即可


为类型添加方法:

type Integer int
func (a Integer) Less(b Integer) bool { // 面向对象
return a < b 
} 
func Integer_Less(a Integer, b Integer) bool { // 面向过程
return a < b 
} 
a.Less(2) // 面向对象的用法
Integer_Less(a, 2) // 面向过程的用法

Go语言和C语言一样,类型都是基于值传递的。要想修改变量的值,只能传递指针

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

值语义和引用语义:

go语言中大部分都为值类型,但是有些特例


数组切片:指向数组(array)的一个区间。
map:极其常见的数据结构,提供键值查询能力。
channel:执行体(goroutine)间的通信设施。
接口(interface):对一组满足某个契约的类型的抽象。


因为其本质都是一个区间

如数组切片

type slice struct {
first *T
len int
cap int
}

go语言中的结构体与类相同,但是同样,不能继承,可以有组合(composition)特性


匿名组合:

type Base struct {
Name string
}
func (base *Base) Foo() { ... }
func (base *Base) Bar() { ... }

type Foo struct {
Base 
...
}
func (foo *Foo) Bar() {
foo.Base.Bar()
}

Foo 类,该类从 Base 类“继承”并改写了 Bar() 方法,如果没有改写该方法,则调用Foo.bar()与调用Foo.Base.bar()效果一致

2.在Go中,可以随心修改内存布局


type Foo struct {
... // 其他成员
Base
}

3.还可以以指针方式从一个类型“派生”


type Foo struct{
*Base
...
}

匿名组合总体来说解决了C++中的虚基类,其好处在于,可以隐藏掉其组合的类X,不必关心其的实现机制。但是同时,组合的类X无法访问该类A的成员变量,因为在写X的时候,A还没有存在,这也是需要考虑的部分

问题:

变量重名,解决方法1, 变量隐藏,2,报错


初始化:


在Go语言中,未进行显式初始化的变量都会被初始化为该类型的零值,例如bool类型的零值为false,int类型的零值为0,string类型的零值为空字符串

type Rect struct {
x, y float64
width, height float64
}

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

由于Go语言没有构造函数(Go语言也没有继承概念),所以使用NewXXX作为构造函数初始化类

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

开发者也不需要分析在使用了new之后到底背后发生了多少事情。在Go语言中,一切要发生的事情都直接可以看到


可见性:

符号定义为以大写字母开头,则该成员可以在包外被访问

若是小写字母开头,则之能够在包内被访问

总结,go语言中符号的可访问性是指 包一级的,在同一个包下的类之间可以无限制访问;若是同c++一样是类型一级的,则类与类之间的访问需要加上关键字friend





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

本文来自:CSDN博客

感谢作者:luan_tianjiao

查看原文:go语言的面向对象

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

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