go语言之面向对象编程

1. 结构体

  • go中没有class这个概念,但有struct
  • 结构体的所有字段在内存中是连续
  • 结构体类型与结构体类型之间也可以相互转换,但是转换需要有完全相同的字段
    • 名字,个数,类型
type A struct{
	Num int
}
type B struct{
	Num int
}

var a A
var b B
a=A(b)

1.1 结构体的声明

type 结构体名称 struct{
	field1 type
	filed2 type
}

1.2 结构体的使用

  • 方式1
p1:=Person{"mary",20}
fmt.Println(p1)

p2:=Person{
	name:"zhangsan",
	age:19,
}
  • 方式2
var p1 *Person=new(Person)
// go中指针可以用.
/**
对于指针p1,go的设计者,为了操作方便,当使用时p1.Name="李四",
底层自动会转换为(*p1).Name="李四"
*/
p1.Name="李四"
  • 方式3
var p1 *Person=&Person{}

1.3 声明时加上tag(用于序列化)

type Monster struct{
	Name string `json:"name"`
	Age int `json:"age"`
	Skill string `json:"skill"`
}

monster :=Monster{"牛魔王",200,"芭蕉扇。。"}
jsonStr,err:=json.Marshal(monster)
if err!=nill{
	处理锁雾
}
fmt.Println("jsonStr",string(jsonStr))
  • 私有字段好像不能被序列化

1.4 给结构体添加方法

  • 在结构体外添加
func (receiver type) methodName(参数列表) (返回值列表){
	方法体
	return 返回值
}
type A struct{
	Num int
}
func (a A) test(){
	fmt.Println(a.Num)
}

var a A
a.Num=10
a.test()
  • go中的方法作用在指定数据类型上的,因此自定义数据类型都可以有方法
  • 而且不仅仅是struct,比如int,float32等都可以有方法
  • 方法首字母小写,只能本包访问,方法首字母大写,其他包也可以访问
  • 如果一个类型实现了String()这个方法,那么fmt.Println默认会调用这个变量的String()进行输出
  • 通过一个变量调用方法时,其调用机制和函数一样,不一样的是,变量调用方法时,该变量本身也会作为一个参数传递到方法
    • 如果是值类型则进行值拷贝
    • 如果是引用类型则进行引用拷贝

1.5 方法与函数的区别

调用方式不一样

  • 函数:函数名(实参列表)
  • 方法:变量.方法名(实参列表)

普通函数,接受者为值类型时,不能将指针类型的数据直接传递,反之亦然
但对于方法,它只看接受者的类型,你可以传值类型,也可以传引用类型,但在方法里都是按照接受者的类型来看待

1.6 工厂模式向其他包提供私有结构体

package model
type student struct{
	Name string
	Score float64
}
func NewStudent(n string,s float64) *student{
	return &student{
		Name:n,
		Score:s,
	}
}

//其他包中
var stu=model.NewStudent("tom~~",99.2)

2. 面向对象

2.1 封装

  • 对结构体中的属性进行封装
type person struct{
	Name string
	age int
	sal float64
}
func NewPerson(name string) *person{
	return &person{
		Name:name,
	}
}
func (p *person) SetAge(age int){
	p.age=age
}
func (p *person) GetAge() int{
	return p.age
}
func (p *person) SetSal(sal float64){
	p.sal=sal
}
func (p *person) GetSal() float64{
	return p.sal
}

// 其他包
p:=model.NewPerson("smith")
p.SetAge(18)
p.SetSal(500)
fmt.Println(p)

2.2 继承

type Goods struct{
	Name string
	Price int
}
type Book struct{
	Goods // 嵌套匿名结构体就是继承
	Writer string
}
  • 结构体可以使用嵌套匿名结构体所有的字段和方法(无论首字母是否大小写)
  • 结构体中的匿名字段还可以是基本数据类型,但不能有多个同一基本数据类型的匿名字段
type Monster struct{
	Name string
	Age int
}
type E struct{
	Monster
	int
	n int
}
var e E
e.Name="张三"
e.Age=11
e.int=20
e.n=40

2.2.1 创建结构体给继承字段也赋值

type Goods struct{
	Name string
	Price float64
}

type Brand struct{
	Name string
	Address string
}
type TV struct{
	Goods
	Brand
}
type Tv1 struct{
	*Goods
	*Brand
}

tv:=TV{Goods{"电视机",500.9},Brand{"海尔","山东"},}
tv1:=TV1{
		&Goods{
			Name:"电视机",
			Price:100.2,
		},
		&Brand{
			Name:"长虹",
			Address:"四川"
		},
	}

2.3 接口

2.3.1 声明接口

type 接口名 interface{
	method1(参数列表) 返回值列表
	...
}
  • go语言中一个结构体(变量)不需要显示地实现接口
  • 只要一个变量,含有该接口类型中的所有方法,那么这个变量就实现了这个接口
type Usb interface{
	Start()
}
type Phone struct{
}
func (p Phone) Start(){
	fmt.Println("手机start")
}
func Working(usb Usb){
	usb.Start()
}
func main(){
	phone :=Phone{}
	Working(phone)
}

2.3.2 接口可以继承其他接口

type BInterface interface{
	test1()
}
type CInterface interface{
	test2()
}
type AInterface interface{
	BInterface
	CInterface
	test3()
}
  • 所有类型都实现了空接口

2.4 多态

2.4.1 多态参数

  • 函数的形参是接口,调用时传入的实参是接口的实现

2.4.1 多态数组

  • 数组是接口数组,存入的时候存入接口的实现
type Usb interface{}
var arr [3]Usb
arr[0]=1
arr[1]=99.1
arr[2]="string"

2.4.2 类型断言

接口变量.(类型)

type Usb interface{}
var a Usb
a="hello world"
str,ok :=a.(string)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值