继承也是面向对象的三大基本特性之一。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。通过继承,不仅可以让某个类型的对象拥有属于自己的数据结构和操作,还会自动拥有父类的数据结构和操作。这使得现有的类在无需重新编写原来类的情况下对这些功能进行了扩展,很好地解决了代码的重用问题。继承机制的魅力和强大在于它允许程序员利用已经存在的类,并且可以以某种方式扩展这个类,而且对其他继承了这个父类属性和方法的对象没有影响。但Go语言没有继承这个概念,它通过匿名组合间接实现了继承的特性。
一、匿名组合实现的属性继承
1.1 匿名字段
在结构体那一章节介绍过Go语言的匿名字段:即只有类型、没有字段名的字段。虽然匿名字段没有名称,但本质上是以类型名为名称的字段。所有内置类型和自定义类型都可以作为匿名字段。
1.2 匿名字段构成的匿名组合
如果结构体中的匿名字段是结构体类型,那么这个结构体所拥有的全部字段都被隐式地引入了当前定义的这个结构体。这种结构体内部嵌套结构体匿名字段的组合被称作匿名组合。而结构体匿名字段中的成员可以通过外部结构体直接访问。
1.3 同名字段构成的匿名组合
外部结构体的成员变量名和嵌入的结构体匿名字段中的成员变量名相同,则此外部结构体成员被称作同名字段。同名字段可以通过外部结构体直接访问,但是匿名字段中与同名字段同名的成员变量的访问需要显式调用,其他成员变量可以通过外部结构体直接访问。
1.4 匿名组合和非匿名组合的区别
和匿名组合相比,非匿名组合有两点不同:
第一,内部的嵌入字段是有变量名的,调用该字段的内部成员需要显式调用;
第二,嵌入字段所拥有的全部字段并没有被隐式地引入当前定义的这个结构体,也就是没有实现继承。
1.5 其他匿名字段
匿名字段不仅可以是结构体类型,还可以是其他任意的内置类型和自定义类型,甚至可以是结构体的指针类型。
1.5.1 非结构体类型
非结构体类型包括:所有的内置类型和自定义类型。
1.5.2 结构体指针类型
匿名字段不仅可以是结构体类型,也可以是结构体指针类型。
二、匿名组合的方法继承与重写
2.1 方法的继承
如果嵌套在结构体内部的匿名字段已经实现了一个方法,那么外部结构体就“继承”了这个方法。外部结构体也可以实现其他方法。
2.2 方法的重写
如果嵌套在结构体内部的是匿名字段,内部结构体实现了方法。外部结构体对此方法进行了修改,这就叫做方法的重写。可以通过外部结构体直接访问重写后的方法,但是匿名字段的方法需要显式调用。
参考资料
[1] 谭浩强.C++面向对象程序设计[M]. 清华大学出版社,2006
[2] 陈维兴,陈昕.C++面向对象程序设计[M]. 人民邮电出版社,2010