go 语言的 struct 可以使用组合来引入另外一个结构,以获得该结构定义的变量和函数。结合 interface,可以模拟面向对象中的继承和多态,但是行为有差异。
以下是 go composite 的示例代码:
type IAnimal interface {
Eat()
Sleep()
EatThenSleep()
}
type Animal struct {
Name string
}
func (d Animal) Eat() {
fmt.Println("animal " + d.Name + " is eating...")
}
func (d Animal) Sleep() {
fmt.Println("animal " + d.Name + " is sleeping...")
}
func (d Animal) EatThenSleep() {
d.Eat()
d.Sleep()
}
type Dog struct {
Animal // 类似继承
}
func (d Dog) Eat() {
// 类似覆盖
fmt.Println("dog " + d.Name + " is eating quickly...")
}
func main() {
var d IAnimal = Dog{Animal{"dog"}}
// 这里会调用 Animal.Eat,而不是 Dog.Eat,这个跟面向对象的动态绑定是不一样的
// Dog 本身没有 EatThenSleep 方法,所以会跳到 Dog.Animal.EatThenSleep 方法
// Dog.Animal.EatThenSleep 方法会调用 Dog.Animal.Eat 而非 Dog.Eat
d.EatThenSleep()
}
以下是 Python 编写的代码:
class Animal(object):
def __init__(self, name):
self.name = name
def eat(self):
print('animal ' + self.name + ' is eating')
def sleep(self):
print('animal ' + self.name + ' is sleeping')
def eat_then_sleep(self):
self.eat()
self.sleep()
class Dog(Animal):
def eat(self):
print('dog ' + self.name + ' is eating quickly')
if __name__ == '__main__':
d = Dog("d")
d.eat_then_sleep() # 会调用 Dog.eat()