Go中struct组合与Java继承的区别

本文阅读 2 分钟
首页 golang 正文

答案:

两者都是在编译期实现的。
Go语言的继承通过匿名组合完成:基类以Struct的方式定义,子类只需要把基类作为成员放在子类的定义中,支持多继承。
Java的继承通过extends关键字完成,不支持多继承。

示例Go代码:

package main

import "fmt"

type People struct{}

func (p *People) ShowA() {
    fmt.Println("people showA")
    p.ShowB()
}

func (p *People) ShowB() {
    fmt.Println("people showB")
}
type Teacher struct {
    People
}
func (t *Teacher) ShowB() {
    fmt.Println("teacher showB")
}
func main() {
    t := Teacher{}
    t.ShowA()
}

//输出结果:
//people showA
//people showB

示例java代码

public class People {
    public void showA() {
        System.out.println("ShowA");
        this.showB();
    }
    public void showB() {
        System.out.println("ShowB");
    }
}

public class Teacher extends People{
    
    public void showB() {
        System.out.println("ShowTeacherB");
    }
    
    public static void main(String[] args){
        Teacher t = new Teacher();
        t.showA();
    }
}

//ShowA  
//ShowTeacherB

在编译期,Go的编译器会自动给Teacher生成一个ShowA函数,内部调用一个People实例的showA函数,这样调用顺序是Teacher.ShowA()->People.ShowA()->People.ShowB()。Go的继承在运行时仍然是一个组合关系,Teacher仍然要通过People的实例去调用People的函数。

func (t *Teacher) ShowA() {
    t.People.ShowA()
}

Java的编译器则会把People ShowA函数的内容拷贝过来给Teacher生成一个ShowA函数,里面的this在运行时对应的就是Teacher的实例,所以调用顺序是Teacher.showA()->Teacher.showB()。Java在运行时Teacher实例内部不会再有People的实例存在。

public void showA() {
    System.out.println("ShowA");
    this.showB();
}

通过以上两段代码发现,go调用ShowB()方法时并没有去子类调用,而是使用父类的ShowB()方法
Go并不支持完全的面向对象,但这并不代表Go不支持面向对象,只是有些地方在使用的时候需要去注意,避免踩坑。

本文来自投稿,不代表本站立场,如若转载,请注明出处:
了解中间件吗?有什么好处?
« 上一篇 09-17
Go 高并发的特点
下一篇 » 09-17

发表评论

发表评论