我听过很多人谈论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(){
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
}
现在,它由Thing Struct构成了Person和Cat Structs。通过这样做,Person和Cat结构不仅与Thing Struct共享相同的Fields,而且通过组合,Thing的方法也被共享。这不是继承吗?同样通过实现这样的接口:
type thing interface {
GetName() string
SetName(name string)
SetAge(age int)
}
所有三个Structs现在都加入了或者我应该说,可以以同质的方式使用,例如一系列“东西”。
所以,我把它放在你身上,这不是继承吗?
修改的
添加了一个名为“Ugly person”的新派生结构,并覆盖了Cat的SetAge方法。
答案 0 :(得分:4)
它是继承,但可能不是你可能会继承的那种继承。您的示例看起来很有希望b / c Person
和Cat
在行为上和结构上彼此相等,以模型名称为模。
只要您尝试使用此“继承”来“扩展”某些基类型,例如添加字段,您就会发现“基类”的接收者始终是基类,从不扩展的。 IOW,你无法实现结构上的多态类型层次结构。
OTOH,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()
}
答案 1 :(得分:2)
这叫做作曲。人或猫的方法无法直接进入Thing的领域。如果是Cat实现了一个自己的SetAge(),你想要调用Thing,你必须调用myCat.Thing.SetAge(42)而不是myCat.SetAge(42)。
答案 2 :(得分:1)
既然您提到了C#,请尝试在go中执行此操作。在Go中不能使方法调用成为虚拟(除了通过接口)。
// 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's years
}
}
}
并像这样调用它:
Thing t = new Cat() {Name="Tom", Age=5}; // a Cat object is assigned
// to a Thing variable
Console.WriteLine(t.Age); // outputs 35.
// t.Age refers to Cat's implementation
// of Age, not Thing's. Notice how Age is virtual
// in Thing and overridden in Cat