如何在Go语言中实现虚拟继承

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

How to realize Virtual Inheritance in Go

问题

  1. 如何在Go语言中实现"虚拟继承"?

  2. Go语言编译器版本:"1.3.1 windows/amd64",它是否支持Go语言的"虚拟继承"?

我从未听说过类似C语言的语言可以支持"虚拟",所以我真的很困惑。

英文:
  1. How to realize "Virtual Inheritance" in Go?

  2. go lang compiler version: "1.3.1 windows/amd64", does it support "Virtual Inheritance" for Go?

I never heard a C like language could support "Virtual", so I really misunderstand.

答案1

得分: 9

虚拟继承 解决了一个在没有多重继承的情况下不存在的问题。考虑以下继承树:

  A
 / \
B   C
 \ /
  D

如果类 B 和 C 都提供了同名的数据成员(或方法),那么在 D 中访问该成员时,你需要一种方式来消除歧义,以确定你希望访问哪个祖先的数据成员(或方法)。

虚拟继承是 C++ 的解决方案。

在 Go 中,你首先没有继承,只有组合,并且你最多只能嵌入一个给定类型的成员。

package main

type B struct {
}

func (b B) Foo() {}

type C struct {
}

func (c C) Foo() {}

type D struct {
	B
	C
}

func main() {
	d := D{B{}, C{}}
	// d.Foo() // <- ambiguous
	d.B.Foo()  // <- ok
    d.C.Foo()  // <- ok
}
英文:

Virtual Inheritance solves a problem which does not exist if you don't have multiple inheritance. Consider the following inheritance tree:

  A
 / \
B   C
 \ /
  D

If classes B and C both provide a data-member (or method for that matter) with the same name then when accessing said member in D, you need a way to disambiguate whose ancestor's data-member (or method) you wish to access.

Virtual Inheritance is C++'s solution.

In Go you don't have inheritance to begin with; only composition and you can embed at most 1 member of any given type at once.

http://play.golang.org/p/1iYzdoFqIC

package main

type B struct {
}

func (b B) Foo() {}

type C struct {
}

func (c C) Foo() {}

type D struct {
	B
	C
}

func main() {
	d := D{B{}, C{}}
	// d.Foo() // &lt;- ambiguous
	d.B.Foo()  // &lt;- ok
    d.C.Foo()  // &lt;- ok
}

答案2

得分: 0

虚拟继承不仅解决了多重继承的问题,还为我们提供了多态性。

package main

import (
	"fmt"
	"math"
)

type Form interface {
	Color() string
	Area() float64
}

type form struct {
	color string
}

func (f *form) Color() string {
	return f.color
}

type Circle struct {
	form
	radius float64
}

func (k *Circle) Area() float64 {
	return math.Pi * k.radius * k.radius
}

type Rectangle struct {
	form
	width, height float64
}

func (r *Rectangle) Area() float64 {
	return r.width * r.height
}

func main() {
	var forms [2]Form
	forms[0] = &Circle{
		form:   form{"black"},
		radius: 5.0,
	}
	forms[1] = &Rectangle{
		form:   form{"read"},
		width:  2.0,
		height: 3.0,
	}
	for _, f := range forms {
		fmt.Printf("%s: %.2f\n", f.Color(), f.Area())
	}
}

在这里,我们有一个具有共同特点(ColorArea)的事物数组,我们可以遍历这个数组,调用相同的函数,总是会发生正确的事情。

这只是多态性的一个优点。它在大多数设计模式中起着重要作用。

英文:

Virtual Inheritance not only solves the problem of multiple inheritance but also gives us polymorphism.

package main

import (
	&quot;fmt&quot;
	&quot;math&quot;
)

type Form interface {
	Color() string
	Area() float64
}

type form struct {
	color string
}

func (f *form) Color() string {
	return f.color
}

type Circle struct {
	form
	radius float64
}

func (k *Circle) Area() float64 {
	return math.Pi * k.radius * k.radius
}

type Rectangle struct {
	form
	width, height float64
}

func (r *Rectangle) Area() float64 {
	return r.width * r.height
}

func main() {
	var forms [2]Form
	forms[0] = &amp;Circle{
		form:   form{ &quot;black&quot; },
		radius: 5.0,
	}
	forms[1] = &amp;Rectangle{
		form:   form{ &quot;read&quot; },
		width:  2.0,
		height: 3.0,
	}
	for _, f := range forms {
		fmt.Printf(&quot;%s: %.2f\n&quot;, f.Color(), f.Area())
	}
}

Here we have an array of things that have something in common (Color and Area) and we can just iterate over this array calling the same functions and always the right thing will happen.

This is just one advantage of polymorphism. It plays a big role in most design patterns.

答案3

得分: -1

"虚拟继承"的示例代码如下:

package main

type A struct {
	virtual int
}

func (a *A) set(v int) {
	a.virtual = v
}

func (a *A) get() int {
	return a.virtual
}

type B struct {
	*A
}

type C struct {
	*A
}

type D struct {
	*B
	*C
}

func main() {
	a := &A{}
	b := &B{a}
	c := &C{a}
	d := &D{b, c}
	d.B.set(3)
	println(d.C.get())
	return
}

你可以在这里查看完整代码:http://play.golang.org/p/8RvPmB3Pof

英文:

"Virtual Inheritance" is something more like this

http://play.golang.org/p/8RvPmB3Pof

package main

type A struct {
    virtual int
}

func (a *A) set(v int) {
     a.virtual = v
}

func (a *A) get() int {
    return a.virtual
}

type B struct {
    *A
}

type C struct {
    *A
}

type D struct {
    *B
    *C
}

func main() {
    a := &amp;A{}
    b := &amp;B{a}
    c := &amp;C{a}
    d := &amp;D{b, c}
    d.B.set(3)
    println(d.C.get())
    return
}

huangapple
  • 本文由 发表于 2014年9月26日 19:06:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/26058133.html
匿名

发表评论

匿名网友

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

确定