Go 中的脆弱基类问题?
尽管拥抱组合而不是继承,但有人担心 Go 是否仍然面临“脆弱基类” “ 问题。本文研究了这个主题,并探讨了语言级别的潜在解决方案。
脆弱基类问题
在经典的面向对象编程中,出现了脆弱基类问题当对基类的修改破坏了依赖其方法的子类时。出现这种情况是由于虚拟方法重写,实际方法实现是在运行时确定的。
Go 中的组合:它会缓解问题吗?
Go 采用组合代替继承,但提供了一种嵌入机制,将嵌入类型的方法包含在嵌入类型中。但是,Go 中不支持方法重写。嵌入类型的所有方法都会被提升并保留在嵌入类型的方法集中。
Go 的豁免:一个示例
为了说明 Go 与面向对象的语言之间的区别对于脆弱基类问题,请考虑以下示例:
type Counter struct { value int } func (c *Counter) Inc() { c.value++ } func (c *Counter) IncBy(n int) { c.value += n } type MyCounter struct { Counter } func (m *MyCounter) Inc() { m.IncBy(1) }
在 Java 中
Java 对方法重写的支持造成了脆弱基类问题的可能性。如果将 Counter.IncBy() 方法修改为:
void incBy(int n) { for (; n > 0; n--) { inc(); } }
MyCounter 将因 MyCounter.Inc() 调用 Counter.IncBy() 时无限循环而变得不可用,从而导致递归调用。
在 Go 中
在 Go 中,对 Counter.IncBy() 进行相同的修改不会导致同样的问题。 MyCounter.Inc() 仍然调用 Counter.Inc(),而 Counter.Inc() 又调用 Counter.IncBy(),但这不会创建循环,因为调用的是 Counter 的 Inc() 函数,而不是 MyCounter 的函数。 Counter 没有对 MyCounter 的引用,保持了其独立性。
结论
而 Go 的组合机制和缺乏方法重写将脆弱的基类问题缓解到了显着的水平。但值得注意的是,它并没有完全消除。
以上是Go 的组合方法是否完全消除了脆弱基类问题?的详细内容。更多信息请关注PHP中文网其他相关文章!