RosettaCodeData/Task/Polymorphism/Go/polymorphism.go

82 lines
2.7 KiB
Go

package main
import "fmt"
type point struct {
x, y float64
}
type circle struct {
x, y, r float64
}
type printer interface {
print()
}
func (p *point) print() {
fmt.Println(p.x, p.y)
}
func (c *circle) print() {
fmt.Println(c.x, c.y, c.r)
}
func main() {
var i printer // polymorphic variable
i = newPoint(3, 4) // assign one type
i.print() // call polymorphic function
i = newCircle(5, 12, 13) // assign different type to same variable
i.print() // same call accesses different method now.
}
// Above is a sort of polymorphism: both types implement the printer
// interface. The print function can be called through a variable
// of type printer, without knowing the underlying type.
// Below is other stuff the task asks for. Note that none of it is
// needed for cases as simple as this task, and it is not idomatic
// to write any of these functions in these simple cases.
// Accessors are not idiomatic in Go. Instead, simply access struct
// fields directly. To allow access from another package, you "export"
// the field by capitalizing the field name.
func (p *point) getX() float64 { return p.x }
func (p *point) getY() float64 { return p.y }
func (p *point) setX(v float64) { p.x = v }
func (p *point) setY(v float64) { p.y = v }
func (c *circle) getX() float64 { return c.x }
func (c *circle) getY() float64 { return c.y }
func (c *circle) getR() float64 { return c.r }
func (c *circle) setX(v float64) { c.x = v }
func (c *circle) setY(v float64) { c.y = v }
func (c *circle) setR(v float64) { c.r = v }
// Copy constructors, not idiomatic. Structs are assignable so
// you can simply declare and assign them as needed.
func (p *point) clone() *point { r := *p; return &r }
func (c *circle) clone() *circle { r := *c; return &r }
// Assignment methods, not idiomatic. Just use the assignment operator.
func (p *point) set(q *point) { *p = *q }
func (c *circle) set(d *circle) { *c = *d }
// Constructors are idiomatic only when construction involves something
// more than just assigning initial values. By default, structs
// are created as "zero values," that is, with all fields zero,
// empty, or nil. The struct literal synax allows for all fields to
// initialized, or for any subset of fields to be initialized by name.
// These feautures take the place of trivial default constructors.
// When additional initialization is needed, it is conventional to
// name a function New, New<Type>, or within a package, new<Type>
// as shown here.
func newPoint(x, y float64) *point {
return &point{x, y}
}
func newCircle(x, y, r float64) *circle {
return &circle{x, y, r}
}
// Destructors are never used in Go. Objects are garbage collected.