Hits

Go面向对象特性

Go面向对象特性

接口

接口使用 interface 关键字声明,任何实现接口定义方法的类都可以实例化该接口,接口和实现类之间没有任何依赖,你可以实现一个新的类来当作Sayer来使用,而不需要依赖Sayer接口,也可以为已有的类创建一个新的接口,而不需要修改任何已有的代码,和其它静态语言相比,这可以算是golang的特色了吧

type Sayer interface {
    Say(message string)
    SayHi()
}

继承

继承使用组合的方式实现

type Animal struct {
    Name string
}

func (a *Animal) Say(message string) {
    fmt.Println("Animal[%v] say: %v\n", a.Name, message)
}

type Dog struct {
    Animal
}

Dog 将继承 AnimalSay 方法,以及其成员 Name

覆盖

子类可以重新实现父类的方法

// override Animal.Say
func (d *Dog) Say(message string) {
    fmt.Println("Dog[%v] say: %v\n", d.Name, message)
}

Dog.Say 将覆盖 Animal.Say

多态

接口可以用任何实现该接口的指针来实例化

var sayer Sayer

sayer = &Dog{
    Animal{Name: "Yoda"}
}
sayer.Say("hello world")

但是不支持父类指针指向子类,下面这种写法是不允许的

var animal *Animal
animal = &Dog{
    Animal{Name: "Yoda"}
}

同样子类继承的父类的方法引用的父类的其他方法也没有多态特性

func (a *Animal) Say(message string) {
    fmt.Printf("Animal[%v] say: %v\n", a.Name, message)
}

func (a *Animal) SayHi() {
    a.Say("Hi")
}

func (d *Dog) Say(message string) {
    fmt.Printf("Dog[%v] say: %v\n", d.Name, message)
}

func main() {
    var sayer Sayer
    sayer = &Dog{Animal{Name: "Yoda"}}
    sayer.Say("Hello world") // Dog[Yoda] say: hello world
    sayer.SayHi() // Animal[Yoda] say: Hi
}

上面这段代码中,子类Dog没有实现SayHi方法,调用的是从父类Animal.SayHi,而Animal.SayHi调用的是Animal.Say而不是Dog.Say,这一点和其它面向对象语言有所区别,需要特别注意,但是可以用下面的方式来实现类似的功能,以提高代码的复用性

func SayHi(s Sayer) {
    s.Say("Hi")
}

type Cat struct {
    Animal
}

func (c *Cat) Say(message string) {
    fmt.Printf("Cat[%v] say: %v\n", c.Name, message)
}

func (c *Cat) SayHi() {
    SayHi(c)
}

func main() {
    var sayer Sayer
    sayer = &Cat{Animal{Name: "Jerry"}}
    sayer.Say("hello world") // Cat[Jerry] say: hello world
    sayer.SayHi() // Cat[Jerry] say: Hi
}

参考链接

本文链接:参与评论 »

--EOF--

Comments