为什么不建议在 go 中使用“继承"?

原创
2021/08/28 15:17
阅读数 231

TL;DR

go 没有虚函数,而 java 函数默认就是虚函数,它会通过动态绑定找到实际应该执行的函数。

严格的说,go 没有继承。我们使用结构体嵌套的方式实现的是一种“伪继承”。

go vs java

我们用典型的 OOP 语言 java 对比一下两者的差异。

go

package main

import "log"

type foo struct {
}
func (f *foo) method1() {
    f.method2()
}
func (f *foo) method2() {
    f.method3()
}
func (f *foo) method3() {
    log.Println("foo")
}

type bar struct {
    foo
}
func (b *bar) method1() {
    b.method2()
}
// func (b *bar) method2() {
    // 	b.method3()
// }
func (b *bar) method3() {
    log.Println("bar")
}
    
func main() {
    bar := &bar{}
    bar.method1() // foo
    bar.method2() // foo
    bar.method3() // bar
}

java

// Foo.java
public class Foo{
    public Foo(){
        
    }
    public void Method1() {
        this.Method2();
    }
    public void Method2() {
        this.Method3();
    }
    public void Method3() {
        System.out.println("foo");
    }
}

// Bar.java
public class Bar extends Foo{
    public Bar(){
        
    }
    public void Method1() {
        this.Method2();
    }
    // public void Method2() {
    //     this.Method3();
    // }
    public void Method3() {
        System.out.println("bar");
    }
}

// Main.java
public class Main
{
    public static void main(String[] args) {
        Bar bar = new Bar();
        bar.Method1(); // bar
        bar.Method2(); // bar
        bar.Method3(); // bar
    }
}

对比

以上两个例子都是 bar 继承 foo 类,都对 bar 类的 method2 进行了注释,但两者的输出完全不同。

事实上,即便是非 go 语言(包括 java),一样不推荐使用继承,大多数情况应该使用组合来代替继承。

Related

[Wiki] Composition over inheritance

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部