Люди говорят: Go не является OO (объектно-ориентированным) языком; не используйте условия OO для Go. Хорошо, позвольте мне описать то, что я могу сделать с OO -Go "polymorphism"
С языком OO, я могу сделать разные животные говорят разные вещи в зависимости от их класса:
cat.Say() // miao
sheep.Say() // bahh
cow.Say() // moo
То же, получающая Area() из фигур.
Однако this go demo code заставило меня поверить, что это невозможно. Ниже приведена Иллюстрация # 1.
Тогда сегодня я нашел this go demo code, что делает его вполне возможным. Ниже приведена Иллюстрация # 2.
Итак, мой вопрос в том, что принципиально отличается между двумя, что делает первый неправильным, а второй правильным? Как сделать первый «работает»?
Приложение # 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.
}
Приложение # 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]
*/
Разница в том, что функция вызывает интерфейс, а другая вызывает функцию типа. – tkausl
Go не заставляет вас использовать OO, но на языке есть все, что нужно сделать OOP –
Связанные/возможные дубликаты: [один] (http://stackoverflow.com/questions/29390736/go-embedded-struct-call-child -метод-вместо-родитель-метод); [Два] (http://stackoverflow.com/questions/30622605/can-embedded-struct-method-have-knowledge-of-parent-child); [Три] (http://stackoverflow.com/questions/29144622/what-is-the-idiomatic-way-in-go-to-create-a-complex-hierarchy-of-structs); [Четыре] (http://stackoverflow.com/questions/36710259/go-ensuring-embedded-structs-implement-interface-without-introducing-ambiguity). – icza