Go语言支持继承吗?

huangapple go评论82阅读模式
英文:

Does Go support Inheritence?

问题

我听过很多人谈论Go语言,说它不支持继承。直到真正使用这种语言之前,我只是随大流听信了传闻。在对这种语言进行一些简单的尝试和掌握基础知识之后,我遇到了这种情况:

package main

type Thing struct {
    Name string
    Age  int
}

type UglyPerson struct {
    Person
    WonkyTeeth bool
}

type Person struct {
    Thing
}

type Cat struct {
    Thing
}


func (this *Cat) SetAge(age int){
    this.Thing.SetAge(age)
}

func (this *Cat) GetAge() int {
    return this.Thing.GetAge() * 7
}

func (this *UglyPerson) GetWonkyTeeth() bool {
    return this.WonkyTeeth
}

func (this *UglyPerson) SetWonkyTeeth(wonkyTeeth bool) {
    this.WonkyTeeth = wonkyTeeth
}

func (this *Thing) GetAge() int {
    return this.Age
}

func (this *Thing) GetName() string {
    return this.Name
}

func (this *Thing) SetAge(age int) {
    this.Age = age
}

func (this *Thing) SetName(name string) {
    this.Name = name
}

现在,这样做是将Person和Cat结构体组合成Thing结构体。通过这样做,Person和Cat结构体不仅共享与Thing结构体相同的字段,而且通过组合,Thing的方法也被共享。这不就是继承吗?此外,通过实现以下接口:

type thing interface {
    GetName() string
    SetName(name string)
    SetAge(age int)
}

这三个结构体现在被连接在一起,或者说可以以同质的方式使用,比如一个"thing"数组。

所以,我向你提出问题,这不是继承吗?

编辑

添加了一个新的派生结构体"UglyPerson",并重写了Cat的SetAge方法。

英文:

I have heard a lot of people talk about Go, and how it does not support inheritance. Until actually using the language, I just went along with the crowd and listened to the hear say. After a little messing about with the language, getting to grips with the basics. I came across this scenario:

    package main

type Thing struct {
	Name string
	Age  int
}

type UglyPerson struct {
	Person
	WonkyTeeth bool
}

type Person struct {
	Thing
}

type Cat struct {
	Thing
}


func (this *Cat) SetAge(age int){
	this.Thing.SetAge(age)
}

func (this *Cat GetAge(){
     return this.Thing.GetAge() * 7
}

func (this *UglyPerson) GetWonkyTeeth() bool {
	return this.WonkyTeeth
}

func (this *UglyPerson) SetWonkyTeeth(wonkyTeeth bool) {
	this.WonkyTeeth = wonkyTeeth
}

func (this *Thing) GetAge() int {
	return this.Age
}

func (this *Thing) GetName() string {
	return this.Name
}

func (this *Thing) SetAge(age int) {
	this.Age = age
}

func (this *Thing) SetName(name string) {
	this.Name = name
}

now, what this does it composes the Person and Cat Structs, from the Thing Struct. By doing so, not only does the Person and Cat struct share the same Fields as the Thing Struct, but also, through composition, the methods of Thing are also shared. Is this not inheritance? Also by implenting an interface as such:

type thing interface {
	GetName() string
	SetName(name string)
	SetAge(age int)
}

All three Structs are now joined or should I say, can be used in a homogenous fashion, such as an array of "thing".

So, I lay it on you, is this not inheritance?

Edit

Added a new derived Struct called "Ugly person" and Overridden the SetAge method for Cat.

答案1

得分: 4

这是继承,但可能不是你想要的那种继承。你的例子看起来很有希望,因为PersonCat在行为和结构上是相等的,只是类型名称不同。

一旦你尝试使用这种“继承”来扩展某个基类型,例如添加字段,你会发现“基类”的接收者始终是基类,而不是扩展类。换句话说,你无法实现结构上多态的类型层次结构。

另一方面,Go通过接口支持纯行为继承。将一个接口嵌入到另一个接口中确实会创建一个继承树。

package main

import "fmt"

type Thing struct {
    Name string
    Age  int
}

func (t *Thing) me() {
    fmt.Printf("I am a %T.\n", t)
}

type Person struct {
    Thing
}

func (p *Person) Iam() {
    fmt.Printf("I am a %T.\n", p)
}

type Cat struct {
    Thing
}

func (c *Cat) Iam() {
    fmt.Printf("I am a %T.\n", c)
}

func main() {
    var p Person
    var c Cat

    p.me()
    p.Iam()

    c.me()
    c.Iam()
}
英文:

It is inheritance but probably not the sort of inheritance you are probably after. Your example look promising b/c Person and Cat are behaviorally and structurally equal to each other modulo the type names.

As soon as you'd attempt to use this "inheritance" to 'extend' some base type with, for example added fields, you'll find that the receiver of the "base class" is always the base class, never the extended one. IOW, you cannot achieve structurally polymorphous type hierarchy.

OTOH, Go supports purely behavioral inheritance via interfaces. Embedding one interface into another does create an inheritance tree.

package main

import "fmt"

type Thing struct {
	Name string
	Age  int
}

func (t *Thing) me() {
	fmt.Printf("I am a %T.\n", t)
}

type Person struct {
	Thing
}

func (p *Person) Iam() {
	fmt.Printf("I am a %T.\n", p)
}

type Cat struct {
	Thing
}

func (c *Cat) Iam() {
	fmt.Printf("I am a %T.\n", c)
}

func main() {
	var p Person
	var c Cat

	p.me()
	p.Iam()

	c.me()
	c.Iam()
}

答案2

得分: 2

这被称为组合。Person或Cat的方法无法直接访问Thing的字段。另外,如果Cat实现了自己的SetAge()方法,而你想调用Thing的SetAge()方法,你需要调用myCat.Thing.SetAge(42),而不是myCat.SetAge(42)。

英文:

It's called composition. Methods of Person or Cat have no direct access to the fields of Thing. Also if e.g. Cat implements an own SetAge() and you want to call the one of Thing you would have to call myCat.Thing.SetAge(42) instead of myCat.SetAge(42).

答案3

得分: 1

由于您提到了C#,请尝试在Go中完成此操作。在Go中无法使用虚拟方法调用(除非通过接口)。

type Thing struct {
	Name string
	Age  int
}

type Person struct {
	Thing
}

type Cat struct {
	Thing
}

func (c Cat) Age() int {
	return c.Thing.Age * 7 // age in cat's years
}

并像这样调用它:

t := Cat{Name: "Tom", Age: 5} // 将Cat对象分配给Thing变量
fmt.Println(t.Age()) // 输出35。
// t.Age引用Cat的Age实现,而不是Thing的实现。
// 注意Thing中的Age是虚拟的,并在Cat中被重写
英文:

Since you mentioned C#, try to do this in go. Method calls can't be made virtual in Go (except through interfaces).

<!-- language: lang-cs -->

// this is C#, not go
public class Thing 
{
	public virtual string Name {get; set;}
	public virtual int Age {get; set;}
}

public class Person : Thing {}
public class Cat : Thing 
{
	public override int Age 
	{
		get
		{
			return base.Age * 7; //age in cat&#39;s years
		}
	}
}

and call it like this:
<!-- language: lang-cs -->

Thing t = new Cat() {Name=&quot;Tom&quot;, Age=5}; // a Cat object is assigned 
                                         // to a Thing variable
Console.WriteLine(t.Age); // outputs 35. 
                          // t.Age refers to Cat&#39;s implementation 
                          // of Age, not Thing&#39;s. Notice how Age is virtual 
                          // in Thing and overridden in Cat

huangapple
  • 本文由 发表于 2013年7月31日 21:57:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/17972462.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定