Go继承与组合

本文讨论了Golang中不支持继承但支持组合的概念,强调了组合与继承在面向对象编程中的不同,以及如何正确识别和使用组合。通过实例说明了组合的隔离性特点,并探讨了何时可能需要使用匿名属性来模拟继承的效果。
摘要由CSDN通过智能技术生成

转载:原文链接

Golang是不支持继承的,因此我们在使用的时候往往使用组合。那么,组合与继承有什么区别呢?组合和继承都是面向对象编程中重要的概念。继承让一个类获得另一个类的属性和方法,形成层级关系,子类可以重用父类的功能。而组合则是将一个类的对象作为另一个类的成员变量,实现代码复用和模块化。继承建立的是"is-a"关系,表示一种类型的扩展;而组合则是"has-a"关系,表示对象之间的包含关系。相比继承,组合更加灵活,降低了类之间的耦合度,使得代码更易于维护和扩展。当然,Golang中,可以让父组件直接获取子组件的公开函数和公开属性。但是子组件和父组件之间依然是隔离的。

看一下如下例子:

package main
import "fmt"
type ClassA struct {}
func (a ClassA) Name() string {  return "ClassA"}
func (a ClassA) PrintName() {  fmt.Printf("I am %s", a.Name())}
type ClassB struct {  ClassA}
func (b ClassB) Name() string {  return "ClassB"}
func main() {  var obj = new(ClassB)  obj.PrintName()}

看似,我们想让classB继承classA,并重写了Name方法。但实际上,classB只是覆盖了Name方法,而没有重写他,对于classB里面的classA,其仍然与classB隔离。当classA访问Name方法时,不会用到classB的Name方法,依然是classA的Name方法。这一点与C++的非虚函数比较相似。这是组合很典型的一个特征:隔离。

为什么会写出上面的代码呢?因为我们误把组合当继承了。ClassB与ClassA的关系不是is-a,也就是ClassB不是ClassA的一种。相反,ClassB拥有了ClassA,他们是has-a关系。也就是ClassA的Name函数和CLassB的Name函数没有关系。就相当于菜篮子里面有苹果,菜篮子有自己的名字,苹果也有自己的名字。那么PrintName函数是属于ClassA的,他打印的是ClassA的名字,那当然和ClassB的Name没关系。只不过我们错误的使用了一些魔法,让原本应该为obj.ClassA.PrintName的方法变成了obj.PrintName。

那么,什么时候我们需要用到匿名属性(类似继承)的这种魔法呢?在我们定义一些结构体时,他们具有相同的属性,并且这些属性与其他属性相对较为隔离。

常见的,我们定义web的返回形参类型:

type Resp {  code int64  msg string}
type LoginResp {  Resp  Data {某种结构}}
type RegisterResp {  Resp  Data {某种结构}}

正如上面,Resp每次请求都会返回的内容,而且其与Data在行为上基本上没有关联。

Go在这方面确实与C更为接近,而不是与C++或者Java更为接近。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值