事物的多种形态
Go中的多态性是在接口的帮助下实现的。定义接口类型,创建实现该接口的结构体对象。
定义接口类型的对象,可以保存实现该接口的任何类型的值。Go语言接口变量的这个特性实现了Go语言中的多态性。
接口类型的对象,不能访问其实现类中的属性字段。
从原始的项目上来看,一个项目例子:
type income interface {
calculate() float64 //计算收入总额
source() string //用来说明收入来源
}
//固定账单项目
type fixedBilling struct {
projectName string //工程项目
biddedAmount float64 //项目招标总额
}
//定时生产项目
type timeAndMaterial struct {
projectName string //工程项目
workHours float64 //工作时长
hourlyRate float64 //每小时工资
}
//固定收入项目
func (f fixedBilling) calculate() float64{
return f.biddedAmount
}
func (f fixedBilling) source() string{
return f.projectName
}
//定时收入项目
func (t timeAndMaterial) calculate() float64{
return t.workHours * t.hourlyRate
}
func (t timeAndMaterial) source() string{
return t.projectName
}
func calculateNetIncome(ics []income) float64{
netIncome := 0.0
for _,ic := range ics{
fmt.Printf("收入名称:%v ,收入金额:%.2f \n",ic.source(),ic.calculate())
netIncome += ic.calculate()
}
return netIncome
}
func testProject1(){
p1 := fixedBilling{"项目1",5000}
p2 := fixedBilling{"项目2",8000}
p3 := timeAndMaterial{"项目3",100,50}
p4 := timeAndMaterial{"项目4",200,50}
ics := []income{p1,p2,p3,p4}
fmt.Printf("总收入为:%.2f \n",calculateNetIncome(ics))
}
这时如果甲方提出,需要添加一个网络点击收入的功能,仅仅需要添加结构体,并实现接口的方法就可以了。
type advertisement struct {
adName string //点击项目名称
clickCount int //点击次数
costPerclick float64 //每次点击的收入
}
//添加实现接口income接口
func (a advertisement) calculate() float64{
//go语言不会像java一样自动转换,必须手动转换才能计算
return float64(a.clickCount) * a.costPerclick
}
func (a advertisement) source() string{
return a.adName
}
再将testProject1()函数添加网络点击收入,即可。
func testProject1(){
p1 := fixedBilling{"项目1",5000}
p2 := fixedBilling{"项目2",8000}
p3 := timeAndMaterial{"项目3",100,50}
p4 := timeAndMaterial{"项目4",200,50}
//添加网络点击收入的新项目
p5 := advertisement{"项目5",10000,1}
p6 := advertisement{"项目6",20000,0.7}
ics := []income{p1,p2,p3,p4,p5,p6}
fmt.Printf("总收入为:%.2f \n",calculateNetIncome(ics))
}