人们说,Go不是一种面向对象的语言;不要在Go上使用OO术语。好的,让我来描述一下我能用OO做什么--
使用OO语言,我可以让不同的动物根据他们的类说不同的话:
cat.Say() // miao
sheep.Say() // bahh
cow.Say() // moo从形状中获取面积()也是如此。
然而,这个go演示代码让我相信这是不可能的。作为Exhibit#1包括在下面。
然后今天,我找到了这个go演示代码,这使它完全成为可能。作为Exhibit#2包括在下面。
所以我的问题是,两者之间有什么根本的区别,使得第一个错误和第二个错误是正确的?如何使第一个“工作”?
Exhibit#1:
// Credits: hutch
// https://groups.google.com/d/msg/golang-nuts/N4MBApd09M8/0ij9yGHK_8EJ
////////////////////////////////////////////////////////////////////////////
/*
https://groups.google.com/d/msg/golang-nuts/N4MBApd09M8/tOO5ZXtwbhYJ
LRN:
Subtype polymorphism: Not applicable (Go doesn't have subtyping).
Although if you embed a struct A implementing interface X into a struct B,
struct B will implement interface X, and can be used instead of struct A in
places where struct A is expected. So, kind of yes.
Robert Johnstone:
interfaces behave similarly to virtual functions, but they are not identical. See the (following) example program by hutch.
*/
package main
import "fmt"
type A struct {
astring string
}
type B struct {
A
bstring string
}
type Funny interface {
strange()
str() string
}
func (this *A) strange() {
fmt.Printf("my string is %q\n", this.str())
}
func (this *A) str() string {
return this.astring
}
func (this *B) str() string {
return this.bstring
}
func main() {
b := new(B)
b.A.astring = "this is an A string"
b.bstring = "this is a B string"
b.strange()
// Output: my string is "this is an A string"
// Many people familiar with OO (and unfamiliar with Go) will be quite
// surprised at the output of that program.
}Exhibit#2:
// Credits: https://play.golang.org/p/Zn7TjiFQik
////////////////////////////////////////////////////////////////////////////
/*
Problem (From Polymorphism-Subtype.go):
https://groups.google.com/d/msg/golang-nuts/N4MBApd09M8/tOO5ZXtwbhYJ
LRN: Subtype polymorphism: Not applicable (Go doesn't have subtyping).
Goal:
This is to demo that "polymorphism" is still doable in Go.
*/
package main
import (
"fmt"
)
type Shape interface {
Area() float32
}
type Point struct {
x float32
y float32
}
// Make sure the structs are different sizes so we're sure it'll work with
// all sorts of types
type Circle struct {
center Point
radius float32
}
func (c Circle) Area() float32 {
return 3.1415 * c.radius * c.radius
}
type Rectangle struct {
ul Point
lr Point
}
func (r Rectangle) Area() float32 {
xDiff := r.lr.x - r.ul.x
yDiff := r.ul.y - r.lr.y
return xDiff * yDiff
}
func main() {
mtDict := make(map[string]Shape)
// No problem storing different custom types in the multitype dict
mtDict["circ"] = Circle{Point{3.0, 3.0}, 2.0}
mtDict["rect"] = Rectangle{Point{2.0, 4.0}, Point{4.0, 2.0}}
for k, v := range mtDict {
fmt.Printf("[%v] [%0.2f]\n", k, v.Area())
}
}
/*
$ go run Polymorphism-Shape.go
[circ] [12.57]
[rect] [4.00]
*/发布于 2016-10-22 19:19:37
你的两个展品在做不同的事情。
在第一个例子中,B嵌入了A,而B没有实现strange()方法本身,所以当您调用b.strange()时,您将得到为A定义的strange()的实现。strange方法的接收方(strange)是b.A,而不是b,因此将打印值b.A.astring。如果希望strange打印bstring,则必须为B定义strange。
这指出了Go和其他面向对象语言之间的一个区别:将A嵌入到B中并不意味着B是A的“子类”,因此在需要A类型的对象时不能使用B类型的对象。但是,由于B继承了A的字段和方法,由A实现的任何接口也都由B实现,并且,除非这些方法是专门为B定义的,否则它们在B中的A上操作,而不是B本身。
在第二个演示中,您有Shape接口,它由Circle和Rectangle类型实现。映射的元素类型是Shape,因此实现该接口的任何类型都可以是映射中的元素。当像在循环中一样使用接口类型的值时,可以调用该值上接口中定义的任何方法,并且将调用与该值的实际类型相对应的定义。
发布于 2016-10-22 19:09:44
首先,我想谈一谈“不可能”部分。
import "fmt"
type Animal interface {
Say() string
}
type Cat struct {}
func (cat Cat) Say() string {
return "miao"
}
type Sheep struct {}
func (sheep Sheep) Say() string {
return "bahh"
}
type Cow struct {}
func (cow Cow) Say() string {
return "moo"
}
func main() {
cat := Cat{}
sheep := Sheep{}
cow := Cow{}
fmt.Println(cat.Say())
fmt.Println(sheep.Say())
fmt.Println(cow.Say())
}这将与你所期望的完全一样。因此,在“不同的结构对同一方法的响应不同”方面存在多态性。
Exhibit#1的意图表明,Go所做的实际上类似于@重载之前的Java铸件。
只需将以下方法添加到第一个示例中,就可以了解该方法的工作原理:
func (this B) strange() {
fmt.Printf("my string is %q\n", this.str())
}https://stackoverflow.com/questions/40195682
复制相似问题