Go语言面向对象编程

本文详细介绍了Go语言中的面向对象编程概念,包括类和方法的使用,如简单实例、指针的差异,以及结构体的定义和初始化。此外,还讨论了可见性规则,接口的定义、实现、赋值及其类型。示例代码展示了如何在Go中实现这些概念。
摘要由CSDN通过智能技术生成

注:安装教程

上一篇

二、面向对象编程

1、类和方法

1.1、简单实例


func main() {
	//第一种调用方式a.Less(b)
	var a Integer = 1
	println("a是否大于b:", a.Less(2))

	//第二种调用方式Less(a,b)
	println("a是否大于b:", Less(2, 1))
}

type Integer int //定义一个Integer类型

/*
	定义比较函数:第一种写法
*/
func (a Integer) Less(b Integer) bool {
	return a < b
}

/*
	定义比较函数:第二种写法
*/
func Less(a Integer, b Integer) bool {
	return a < b
}

1.2、指针

1、Go语言中的面向对象最为直观,也无需支付额外的成本。如果要求对象必须以指针传递,这有时会是个额外成本,因为对象有时很小(比如4字节),用指针传递并不划算。
只有在你需要修改对象的时候,才必须用指针。它不是Go语言的约束,而是一种自然约束。举个例子


func main() {
	/*
		函数两种区别:
		打印结果如下:
			LessOne:a= 3
			a=: 1
			LessOne:a= 4
			a=: 4
		总结:
			加*表示指针,指向对象a可以修改a的值
			不加*星号,方法内a修改,外部不修改
	*/
	//第一种
	var a Integer = 1
	a.LessOne(2)
	println("a=:", a) //输出a=: 1

	//第二种
	a.LessTwo(3)
	println("a=:", a) //输出a=: 4
}

type Integer int //定义一个Integer类型

/*
定义相加函数:第一种写法
*/
func (a Integer) LessOne(b Integer) {
	a += b
	println("LessOne:a=", a)
}

/*
定义相加函数:第二种写法
*/
func (a *Integer) LessTwo(b Integer) {
	*a += b
	println("LessOne:a=", *a)
}

2、引用类型
如果b的修改不会影响a的值,那么此类型属于值类型。如果会影响a的值,那么此类型是引用类型。


func main() {
	/**
	数组类型赋值b=a是将内容完全复制,如果想表达引用使用指针。
	例:修改b,a不会改变 修改c,a会改变
	*/
	var a = [3]int{1, 2, 3}
	var b = a
	b[1]++
	fmt.Println(a, b) //输出:[1 2 3] [1 3 3]

	var c = &a
	c[1]++
	fmt.Println(a, *c) //输出:[1 3 3] [1 3 3]
}

1.3、结构体定义和初始化

  1. 结构体=类+方法
  2. 在Go语言中,未进行显式初始化的变量都会被初始化为该类型的零值,例如bool类型的零值为false,int类型的零值为0,string类型的零值为空字符串。
  3. 在Go语言中没有构造函数的概念,对象的创建通常交由一个全局的创建函数来完成,以NewXXX来命名,表示“构造函数”:

func main() {
	//初始化
	u1 := new(User)                       //输出:&{  }
	u2 := User{}                          //输出:{  }
	u3 := User{"binshao", "18", "男"}      //输出:{binshao 18 男}
	u4 := User{age: "18", name: "liming"} //输出:{liming 18 }

	//使用构造函数初始化
	u5 := NewUser("zhangsan", "12", "女") //输出:&{zhangsan 12 女}

	fmt.Println(u1)
	fmt.Println(u2)
	fmt.Println(u3)
	fmt.Println(u4)
	fmt.Println(u5)
}

type User struct { //自定义类
	name string
	age  string
	sex  string
}

func (u *User) getIntroduce() string { //定义类中的方法
	return "名字:" + u.name + " 年龄:" + u.age + " 性别:" + u.sex
}

func NewUser(name, age, sex string) *User { //定义类的构造函数
	return &User{name, age, sex}
}

1.4、可见性

大写字母开头,表示可以被其他包访问到,小写字母只能本包访问。
例如:User类型的成员变量就全部被导出了,可以被所有其他引用了User所在包的代码访问到。
成员方法的可访问性遵循同样的规则,User中getUser()方法只能在该类型的包内使用

type User struct {
	Name string
	Sex  string
}

func (u *User) getUser() string {
	return "姓名:" + u.Name + " 性别:" + u.Sex
}

注意:Go语言中符号的可访问性是包一级的而不是类型一级的。在上面的例子中,尽管getUser是User的内部方法,但同一个包中的其他类型也都可以访问到它。这样的可访问性控制很粗旷,很特别,但是非常实用。如果Go语言符号的可访问性是类型一级的,少不了还要加上friend这样的关键字,以表示两个类是朋友关系,可以访问彼此的私有成员。

2、接口

2.1、接口定义与实现

在Go语言中,一个类只需要实现了接口要求的所有函数,我们就说这个类实现了该接口

/*
例如:
IUser、IGetName、IGetSex、IGetAge中的方法被User全部实现
*/
func main() {
	/*
		尽管User类并没有从这些接口继承,甚至不知道这些接口的存在,但是User类实现了
		这些接口,可以进行赋值,如下:
	*/
	var user1 IUser = new(User)
	var user2 IGetName = new(User)
	var user3 IGetAge = new(User)
	var user4 IGetSex = new(User)

	fmt.Println(user1.getName())
	fmt.Println(user2.getName())
	fmt.Println(user3.getAge())
	fmt.Println(user4.getSex())
}

type User struct {
	Name string
	age  int
	sex  string
}

func (u *User) getName() (name string, err error) {
	return u.Name, nil
}

func (u *User) getAge() (age int, err error) {
	return u.age, nil
}

func (u *User) getSex() (sex string, err error) {

	return u.sex, nil
}

type IUser interface {
	getName() (name string, err error)
	getAge() (age int, err error)
	getSex() (sex string, err error)
}

type IGetName interface {
	getName() (name string, err error)
}

type IGetAge interface {
	getAge() (age int, err error)
}

type IGetSex interface {
	getSex() (sex string, err error)
}

2.2、接口赋值

接口赋值
1、将对象实例赋值给接口;
2、将一个接口赋值给另一个接口。


func main() {

	user := User{"wang", 19, "男"}

	/*
		对象赋值接口
		结论:实例赋值接口是使用"&"
	*/
	var user1 IUser = user  //报错
	var user2 IUser = &user //成功

	/*
		接口赋值接口
		结论:一个接口赋值给另一个接口时,必须实现另一个接口的所有方法

	*/
	var user3 IUser = &user    //成功
	var user4 IGetName = user3 //成功
	var user5 IUser = user4    //报错
	var user6 IGetAge = user4  //报错

}

2.3、接口类型

在Go语言中,还可以更加直截了当地询问接口指向的对象实例的类型,例如


func main() {
	var v interface{} = "字符串"
	switch v.(type) {
	case int:
		println("int类型")
	case string:
		println("string类型")
	default:
		println("类型缺省")
	}
}

评论 44
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值