这是我参与8月更文挑战的第26天,活动详情查看:8月更文挑战
同一个结构体继承了多个不同的结构体
多个不同结构体有相同字段时,如何使用?
在model
包,新建payment_other.go
文件, 这里我们将结构体paymentOther
,结构体内容同PaymentArgs
相同,payment_other.go
的内容
package model
// 微信支付
// 支付宝
// 银联
// 银行卡
type PaymentOther struct {
AppID string
MchID string
Key string
CallbackUrl string
}
这里我们让Alipay
这个结构体同时继承PaymentArgs
和PaymentOther
, Alipay.go
的内容
package model
import "fmt"
type Alipay struct {
PaymentArgs // 匿名结构体
PaymentOther PaymentOther // 有名结构体
AlipayOpenID string
string
}
这里Alipay
结构体想访问AppID
字段就必须指定结构体名,这里有两个概念匿名结构体
和有名结构体
匿名结构体
在嵌套结构体时没有指定结构体变量名,例如上面Alipay
结构体中的PaymentArgs
有名结构体
在嵌套结构体时没有指定结构体变量名,例如上面Alipay
结构体中的PaymentOther
因为他们具有相同的字段,如果想访问Alipay
结构体中的AppID
就必须指定结构体变量名或者匿名结构体名
在main.go
中,如下的访问
fmt.Println(alipay.PaymentOther.AppID)
fmt.Println(alipay.PaymentArgs.AppID)
方法的继承与重载
我们为payment.go
文件中PaymentArgs
结构体增加方法
func (this *PaymentArgs)Info() {
fmt.Printf("Info = %v\n",this)
}
这样我们定义的Alipay
结构体与WeixinPay
结构体自动就继承了PaymentArgs
的方法
我们在main.go
中调用
paymentArgs := model.PaymentArgs{
AppID: "superAppid",
MchID: "superMchid",
Key: "superKey",
CallbackUrl: "https://api.luboke.com/super",
}
paymentArgs.Info()
同样的我们可以对继承的方法进行重定义
在我们的Alipay.go
中为Alipay
结构体增加方法
func (this *Alipay)Info() {
fmt.Printf("alipay = %v\n",this)
}
此时Alipay
结构体重写了Info()
方法,在main.go
中调用
alipay := &model.Alipay{
PaymentArgs: model.PaymentArgs{
AppID:"alipay123",
MchID:"alipaymchid",
Key:"alipayfjkadsfjkasfjas",
CallbackUrl:"https://api.luboke.com/alipay",
},
AlipayOpenID: "alipayopenid",
}
alipay.Info()
结构体继承访问流程
这里以上面
Alipay
结构体当中访问AppID
为例
1.先判断AppID
是否属于Alipay
,如果有就访问
2.如果没有,继续去找他继承的结构体PaymentArgs
,如果有就访问
3.如果没有继续去找PaymentArgs
这个结构的所继承的结构体,如果有就访问,没有就报错,因为PaymentArgs
结构体没有再继承别的结构体
结构体注意事项
1.如果一个结构中继承了多个结构体,而这些多个结构体当中有相同的字段,那么我们就需要使用 结构体名来访问
如上面我们所演示的访问Alipay
结构体中的AppID
就必须指定结构体变量名或者匿名结构体名
2.一个内置类型可以做为结构体的匿名字段,这种方式只能在本包访问
//定义一个结构体,字段为一个内置string类型
type StringStruct struct {
string
}
ss := StringStruct{"hello"}
//这种方式只能在本包中访问
fmt.Println(ss.string)
继承有什么优点
1.提高代码的复用率
2.提高代码的扩展性与维护性