第一回合:面向对象没有使用接口的实现:
这个例子先是创建了一个Person对象,并带有SetName和GetName方法,然后Soldier继承Person增加了grade属性和Attack方法,Attack每执行一次,grade + 1。
//test.go
package main
import "fmt"
type Person struct {
name string
}
//没有意义的返回值,只是用来作语法参考
func (self *Person) SetName(name string ) bool {
self.name = name
return true
}
func (self *Person) GetName() {
fmt.Printf("My name is %s.\n",self.name)
}
type Soldier struct {
Person
grade int
}
func (self *Soldier) Attack() {
fmt.Printf(" %s to take part in a campaign!\n", self.name)
self.grade +=1
}
func (self *Soldier) GetGrade(){
fmt.Println(self.grade)
}
func main(){
p :=Soldier{personObject : personObject{name:"goudan"},grade:1}
p.GetName()
p.SetName("zhangli")
p.GetName()
p.Attack()
p.GetGrade()
最终结果:
$ go run test.go
My name is goudan.
My name is zhangli.
zhangli to take part in a campaign!
2
这里有个坑需要注意:在定义方法时,一定要使用指针,否则实例化的属性不能通过该方法修改,因为通过没有指针的方法设置的属性值所保存的内存地址与实例化的属性值不同。 可以通过func (self *Soldier) Attack()替换成func (self Soldier) Attack()再运行查看p.GetGrade()执行效果。
第二回合:使用接口的面向对象
//test.go
package main
import "fmt"
type Human interface{
GetName()
SetName(string) bool
Attack()
GetGrade()
}
type Person struct {
name string
}
//没有意义的返回值,只是用来作语法参考
func (self *Person) SetName(name string ) bool {
self.name = name
return true
}
func (self *Person) GetName() {
fmt.Printf("My name is %s.\n",self.name)
}
type Soldier struct {
Person
grade int
}
func (self *Soldier) Attack() {
fmt.Printf(" %s to take part in a campaign!\n", self.name)
self.grade +=1
}
func (self *Soldier) GetGrade(){
fmt.Println(self.grade)
}
func main(){
//绑定Human接口
var p Human = Soldier{
Person : Person{name:"goudan"},
grade:1
}
p.GetName()
p.SetName("zhangli")
p.GetName()
p.Attack()
p.GetGrade()
执行结果:
$ go run test.go
My name is goudan.
My name is zhangli.
zhangli to take part in a campaign!
2
最终结果与没有接口的实现并没有不同,但是使用接口的好处有一点,就是要实现的类中的方法(包括继承的)必须要在interface中先定义好,这样在类中实现了哪些方法会在interface中一目了然。