首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

go语言面向对象编程

一.初始化

代码示例:

packagemain

import"fmt"

typeRectstruct{

x, y float64

width, height float64

}

func(this *Rect) Area () float64 {

returnthis.width * this.height

}

funcmain() {

rect1 := new(Rect)

rect2 := &Rect{}

rect3 := &Rect{,,100,200}

rect4 := &Rect

fmt.Println(rect1.Area())

fmt.Println(rect2.Area())

fmt.Println(rect3.Area())

fmt.Println(rect4.Area())

}

在定义Rect之后,咱们通过以下几种方式初始化Rect类型的对象实例:

rect1 := new(Rect)

rect2 := &Rect{}

rect3 := &Rect{,,100,200}

rect4 := &Rect

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

在go语言中,没有构造函数这个概念,对象的创建通常交由一个去全局函数来完成,以NewXXX来命名,表示“构造函数”。

funcNewRect(x, y, width, height float64) *Rect {

return&Rect

}

二.匿名组合

1.匿名组合解释

在go语言,我们是不能明显看到继承,实际上,go语言也提供继承,但是它采用组合文法,所以我们称之为匿名组合。

typeBasestruct{

Name string

}

typeFoostruct{

*Base

}

func(base* Base) Foo() {}

func(base* Base) Bar() {}

func(foo *Foo) Bar() {

foo.Base.Bar()

}

Base类:

实现Foo()成员方法

实现Bar()成员方法

Foo类:

从Base类继承并改写了Bar()方法(该方法实现时先调用了基类

的Bar()方法)。

如果在派生类Foo没有改写基类Base的Bar方法,相应的方法被继承,其实上面的例子中调用Foo.foo()和调用foo.Base.Foo(),效果完全一样

与其他语言不一样的是咱们的go语言很清晰地告诉你内存布局是怎么的。当然,在go语言中你可以随心所欲地修改内存的布局。

上面代码中:

typeFoostruct{

*Base

}

也可以改写为:

typeFoostruct{

Base

}

对应*Base的派生,Foo创建实例的时候,需要外部提供一个Base类的实例指针。

2.Effective Go上面的小案例:

typeJopstruct{

Command string

*log.Logger

}

func(this *Jop) Start() {

this.Log("starting now...")

//....很多事要做

this.Log("started")

}

上面例子中,对于Jop实现者来说,根本没有必要意识到log.Logger的存在。

这就是匿名组合优势所在。那这是为什呢?

解释:组合的类型并不知道自己被什么类型组合,当然就没发在实现方法

的时候去使用未知的一个组合者的功能了。

3.匿名组合中的名字冲突问题

1).场景一

typeXstruct{

Name string

}

typeYstruct{

X

Name string

}

组合类型和被组合的类型都包含一个Name成员,这样是没有任何问题,

所有Y类型的Name成员的访问都只会访问最外层的那个Name变量,X.Name

变量相当于被隐藏

2).场景2

typeLoggerstruct{

Level int

}

typeYstruct{

*Logger

Name string

*log.Logger

}

存在Logger冲突,这样有时是会报错,但是有事编译器并不会告

诉错,直到开发者使用其中某个Logger时,才会告诉你冲突了。

三.可见性

在go语言中,实际上是没有private,protect和public等关键,go语言中要使某个符号对其它包可见(可访问),需要将该符号定义为大写字母开头。

packagehandle

import(

"errors"

"fmt"

)

funcAdd(a, b, c int) (ret int, err error){

ifa

err = errors.New("不能有负数存在")

return1, err

}

ArrayBianli()

returna + b + c, err

}

funcArrayBianli() {

arr :=[10]int{1,3,5,6,7,9}

fori :=; i

fmt.Print(arr[i],", ")

}

fmt.Println("")

}

packagemain

import"main/pkg/handle"

funcmain() {

handle.Add(1,2,3)

handle.ArrayBianli()

}

小写在本包内可以被访问,不能跨包访问,大写本包内可以访问,跨包也可以访问。

和C++一样,在go语言中也有friend关键字。做为扩展知识,大家可以去网上了解一下go语言的friend关键字。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180505G1GO8P00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券