GO语言面向对象编程之方法

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

#GO语言面向对象编程之方法(上)# <font size=5>学过C++或者JAVA的程序员,对于面向对象编程应该是很熟悉的。大家都知道面向对象编程的三大基本特征:封装,继承,多态。在GO语言中,简化了很多面向对象编程的概念,比如 继承,虚函数,构造函数,析构函数,隐藏指针等。对于接触过面向对象编程的人来说,GO语言的面向对象编程更加的简单易懂。</font> ##方法(类)的定义 <font size = 4>在函数声明时,在其名字之前放上一个变量,即是一个方法。这个附加的参数会将该函数附加到这种类型上,即相当于为这种类型定义了一个独占的方法。</font> package main import "math" import "fmt" type Point struct { x float64 y float64 } func TraDistance(p1 Point, p2 Point) float64 { return math.Hypot(p1.x-p2.x, p1.y-p2.y) } func (p1 Point) ObjDistance(p2 Point) float64 { return math.Hypot(p1.x-p2.x, p1.y-p2.y) } func main() { p1 := Point{10, 20} p2 := Point{20, 10} old_len := TraDistance(p1, p2) new_len := p1.ObjDistance(p2) fmt.Println("The result of old method is ", old_len) fmt.Println("The result of OBJ method is ", new_len) } <font color = red>在Go语言里,我们为一些简单的数值、字符串、slice、map来定义一些附加行为很方便。方法可以被声明到任意类型,只要不是一个指针或者一个interface。</font> **** ##指针对象 引入指针对象的原因在于GO语言和C语言一样,都是基于值传递的,什么意思哪,就是你调用函数的时候,对对象的值进行了拷贝,所以是没法修改对象内部的值的,看下面的例子: type Shape struct { length float64 height float64 weight float64 } func (s Shape) ChangeHeight(value float64) { s.height = value } triangle := Shape{1, 3, 4} triangle.ChangeHeight(10) fmt.Println(triangle.height) //输出3 func (s *Shape) ChangeHeightWithPoint(value float64) { s.height = value } triangle := Shape{1, 3, 4} //(&triangle).ChangeHeightWithPoint(10) //triangle.ChangeHeightWithPoint(10) fmt.Println(triangle.height) //上面两种调用方法都可以改变对象的值 对于第二种为什么两种方法都可以调用哪?因为GO语言帮我们做了隐式转换,当然我们也可以用指针来调用非指针的,就像上面的第triangle.ChangeHeight(10)也可以写成(&triangle).ChangeHeight(10),同样的GO语言也会帮你隐式转换成非指针。 *** ##通过嵌入式结构体扩展类型(类似继承) 前面的时候说过结构体的嵌入和匿名函数。我们看下面的一个例子: type Point struct { x float64 y float64 } type Shape struct { Point length float64 height float64 weight float64 } func (p1 Point) ObjDistance(p2 Point) float64 { return math.Hypot(p1.x-p2.x, p1.y-p2.y) } p1 := Point{10, 20} p2 := Point{20, 10} triangle := Shape{p1, 1, 3, 4} len := triangle.ObjDistance(p2) fmt.Println(len) Shape是可以直接对Point对象的函数进行调用的,看到这里是不是感觉这就是c++里面的继承,那我们再看下面这个例子: p1 := Point{10, 20} p2 := Point{20, 10} triangle := Shape{p1, 1, 3, 4} triangle2 := Shape{p2, 1, 3, 4} fmt.Printf("The point2 value in triangle2 x=%f,y=%f", triangle2.x, triangle2.y) len := triangle.ObjDistance(triangle2) 这个时候编译程序会有下面的错误: <font color = red>cannot use triangle2 (type Shape) as type Point in argument to triangle.Point.ObjDistance</font> 对于函数ObjDistance来说,参数Point类型不能用Shape类型,即使Shape类型可以直接访问Point的变量.但对于c++或者java来说,子类是可以作为参数传递的,如下面的代码: #include<iostream> using namespace std; class Parent { public: int x = 10 ,y = 20; }; class Child : public Parent { public: int m,n; }; int test(Parent s) { cout << s.x <<s.y; } int main() { Child childObj; test(childObj);//编译和运行没问题 } 所以GO语言的“继承”并不等同于其它面向对象语言的继承。 *** ##方法值和方法表达式 方法的值: func (p1 Point) ObjDistance(p2 Point) float64 { return math.Hypot(p1.x-p2.x, p1.y-p2.y) } p1 := Point{10, 20} p2 := Point{20, 10} p1Func := p1.ObjDistance p1Func(p2) 方法的表达式: func (p1 Point) ObjDistance(p2 Point) float64 { return math.Hypot(p1.x-p2.x, p1.y-p2.y) } p1 := Point{10, 20} p2 := Point{20, 10} p2Func := Point.ObjDistance p2Func(p1, p2) 方法的表达式看着比函数多了一个参数,这是因为方法的表达式会把第一个参数作为接收器,后面的参数才是函数的真正参数。 ##封装 在C++里面,我们使用public,private,protected关键字来作为变量或者函数的权限设置,但在Go语言中,前面已经说过,GO语言只有大小写的区别,如果想把函数或者变量暴露在外部,那么就首字母大写,相反则小写。</font>

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

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

903 次点击  
加入收藏 微博
被以下专栏收入,发现更多相似内容
7 回复  |  直到 2017-08-21 01:41:22
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传