首页  >  文章  >  后端开发  >  Go 的组合模型还会受到脆弱基类问题的困扰吗?

Go 的组合模型还会受到脆弱基类问题的困扰吗?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-10-27 12:18:02862浏览

 Can Go's Composition Model Still Suffer From the Fragile Base Class Problem?

Go 中的脆弱基类问题:尽管组合优于继承

当对基类的更改可能导致意外时,就会出现脆弱基类问题派生类中的行为。这个问题通常归因于继承,派生类继承其基类的方法和字段。

Go 中没有实现继承。相反,Go 使用组合,其中一个结构可以包含其他结构的实例。然而,一些人认为,在使用嵌入式类型时,Go 中仍然存在脆弱的基类问题。

嵌入式类型将嵌入式类型的字段和方法提升为包装类型。虽然这提供了方便的访问,但它消除了多态性。这意味着嵌入类型中定义的方法不能在包装类型中重写,并且嵌入类型进行的任何方法调用都将始终调用原始定义。

因此,存在脆弱基类问题在 Go 中以一种简化的形式。对嵌入类型的方法或字段的更改可能会影响包装器类型,但前提是包装器类型没有定义自己的同名方法。

示例

考虑以下 Java 代码,其中基类 Counter 包含增量方法 inc() 和增量方法 incBy()。派生类 MyCounter 重写 inc() 来调用 incBy(1)。

<code class="java">class Counter {
    int value;
    void inc() { value++; }
    void incBy(int n) { value += n; }
}

class MyCounter extends Counter {
    @Override
    void inc() { incBy(1); }
}</code>

如果将基类中的 incBy() 方法改为使用循环,则派生类 MyCounter 将进入无限循环因为 inc() 调用了 incBy() ,而 incBy() 又调用了 inc() :

<code class="java">void incBy(int n) {
    for (; n > 0; n--) { inc(); }
}</code>

在 Go 中,同一示例不会出现此问题,因为 Go 不支持嵌入类型中的重写方法:

<code class="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) }</code>

即使将 Counter 类型中的 IncBy() 方法修改为使用循环,MyCounter 类型也不会继承此行为,因为它没有定义名为 Inc() 的方法。相反,它调用 Counter 类型中定义的原始 inc() 方法。

因此,由于嵌入类型缺乏多态性,脆弱的基类问题不是 Go 中的主要问题,这可以防止意外行为修改嵌入类型时。

以上是Go 的组合模型还会受到脆弱基类问题的困扰吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn