Go语言面向对象编程——结构化 方法 继承

Go语言面向对象编程——结构化 方法 继承

本文是学校选修课笔记

author: fengclchn@outlook.com


  • go语言支持类似于C语言中的面向对象的风格

1.结构体(类)定义

定义格式如下:

type 类型名 struct {
    字段1 字段1类型
    字段2 字段2类型
    …
}
  • **类型名:**标识自定义结构体的名称,在同一个包内不能重复

  • **字段1、字段2 ……:**表示结构体字段名,结构体中的字段名必须唯一

  • **字段1类型、字段2类型……:**表示结构体各个字段的类型

//定义一个点类,坐标x y均为float64类型
type Point struct {
	x float64
	y float64
}

同类型变量可以写在同一行

以下语句同上面的语句等价

//定义一个点类,坐标x y均为float64类型
type Point struct {
	x,y float64
}
  • 可见性规则
    • 成员或方法首字母大写 public
    • 成员或方法首字母小写 private
// object project main.go
package main

import (
	"fmt"
)

//对象
type Point struct {
	x float64
	y float64
}

func main() {
	var p *Point = new(Point)
	//通过内置函数new来建立对象,new返回一个指针,指向一块内存单元,其所占存储槽初始化为零。
	p.x = 3 //p虽然是指针,但用取成员运算符即可,不需指向运算符
	p.y = 4

	q := new(Point) //这样也可
	q.x = 5
	q.y = 6

	r := Point{7, 8}              //直接初始化,value
	var s Point = Point{9, 10}    //完整直接初始化,value
	var t *Point = &Point{11, 12} //完整直接初始化,pointer
	u := &Point{13, 14}           //简写,pointer
	fmt.Println(p)
	fmt.Println(q)
	fmt.Println(r)
	fmt.Println(s)
	fmt.Println(t)
	fmt.Println(u)
}

object1

2.方法

  • 声明了类,就可以将该类型显示的作为第一个参数来定义方法

  • eg.坐标变换器

// object project main.go
package main

import (
	"fmt"
	"math"
)

//对象
type Point struct {
	x float64
	y float64
}

func (self Point) Distance() float64 { //self为自身对象,实际上是函数的参数
	return math.Sqrt(self.x*self.x + self.y*self.y)
}

func (self *Point) Scale(factor float64) { //坐标放大器
	self.x *= factor
	self.y *= factor
}

func main() {
	p1 := Point{3, 4}
	fmt.Println(p1.Distance())
	p1.Scale(2) //坐标放大2
	fmt.Println(p1)
}

object2

  • 在函数名前定义接收器,表示该方法作用的目标,也是方法的第一个参数
  • 接收器类型和参数类型类似,可以是指针类型和非指针类型
  • **方法名、参数列表、返回参数:**格式与函数定义一致
  • 官方建议使用接收器类型名的第一个小写字母,也可自己定义
//接收器变量为 Point型
func (self Point) Distance() float64 { //self为自身对象,实际上是函数的参数
	return math.Sqrt(self.x*self.x + self.y*self.y)
}

//接收器变量为 Point型指针
func (self *Point) Scale(factor float64) { //坐标放大器
	self.x *= factor
	self.y *= factor
}
  • 注意 在计算机中,小对象由于值复制时的速度较快,所以适合使用非指针接收器,大对象因为复制性能较低,适合使用指针接收器,在接收器和参数间传递时不进行复制,只是传递指针。

3.继承

// object project main.go
package main

import (
	"fmt"
	// "math"
)

//继承
//定义user类
type user struct {
	name string
	age  byte
}

//定义方法
func (u user) Output() string {
	return fmt.Sprintf("%+v", u) //Sprintf表示格式化输出为字符串
}

//定义leader类
type leader struct {
	user  //匿名成员,实现继承
	title string
}

func main() {
	var l leader
	l.name = "Tim" //继承user.name
	l.age = 19     //继承user.age
	l.title = "sales manager"
	fmt.Println(l.Output()) //继承user.Output()

	//匿名成员有和类型一样的名字,所以可以这样
	l.user.name = "Tom"          //未继承user.name
	l.user.age = 20              //未继承user.age
	fmt.Println(l.user.Output()) //未继承user.Output()
}

object3

  • go通过匿名组合来实现类似继承的功能,在子类中匿名声明父类即可
  • 子类继承后可以通过 “.” 直接访问父类成员,如:l.name = "Tim"
  • 也可以不进行继承,通过访问匿名成员来访问父类成员,如:l.user.name = "Tom"
  • Sprintf表示格式化输出为字符串

4.总结

面向对象只是换了一种语法方式表达而已


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值