package main
import "fmt"
// class Doorbell
type Doorbell struct {
}
func (this Doorbell) Ring() {
fmt.Println("Ring, Ring! Can I come in?")
}
// class Telephone
type Telephone struct {
}
func (this Telephone) Ring() {
fmt.Println("Ring, Ring! Can we talk?")
}
// interfaces are like static duck-typing
type Ringer interface {
Ring()
}
// this function takes any object that has a "Ring" method
func ringThis(r Ringer) {
r.Ring()
}
// we could even use an anonymous interface
func ringThisAnon(r interface { Ring() }) {
r.Ring()
}
func main() {
// all of this typechecks!
ringThis(Doorbell{})
ringThis(Telephone{})
ringThisAnon(Doorbell{})
ringThisAnon(Telephone{})
}
cGFja2FnZSBtYWluCgppbXBvcnQgImZtdCIKCi8vIGNsYXNzIERvb3JiZWxsCgp0eXBlIERvb3JiZWxsIHN0cnVjdCB7Cn0KCmZ1bmMgKHRoaXMgRG9vcmJlbGwpIFJpbmcoKSB7CglmbXQuUHJpbnRsbigiUmluZywgUmluZyEgQ2FuIEkgY29tZSBpbj8iKQp9CgovLyBjbGFzcyBUZWxlcGhvbmUKCnR5cGUgVGVsZXBob25lIHN0cnVjdCB7Cn0KCmZ1bmMgKHRoaXMgVGVsZXBob25lKSBSaW5nKCkgewoJZm10LlByaW50bG4oIlJpbmcsIFJpbmchIENhbiB3ZSB0YWxrPyIpCn0KCi8vIGludGVyZmFjZXMgYXJlIGxpa2Ugc3RhdGljIGR1Y2stdHlwaW5nCgp0eXBlIFJpbmdlciBpbnRlcmZhY2UgewoJUmluZygpCn0KCi8vIHRoaXMgZnVuY3Rpb24gdGFrZXMgYW55IG9iamVjdCB0aGF0IGhhcyBhICJSaW5nIiBtZXRob2QKCmZ1bmMgcmluZ1RoaXMociBSaW5nZXIpIHsKCXIuUmluZygpCn0KCi8vIHdlIGNvdWxkIGV2ZW4gdXNlIGFuIGFub255bW91cyBpbnRlcmZhY2UKCmZ1bmMgcmluZ1RoaXNBbm9uKHIgaW50ZXJmYWNlIHsgUmluZygpIH0pIHsKCXIuUmluZygpCn0KCmZ1bmMgbWFpbigpIHsKCS8vIGFsbCBvZiB0aGlzIHR5cGVjaGVja3MhCglyaW5nVGhpcyhEb29yYmVsbHt9KQoJcmluZ1RoaXMoVGVsZXBob25le30pCglyaW5nVGhpc0Fub24oRG9vcmJlbGx7fSkKCXJpbmdUaGlzQW5vbihUZWxlcGhvbmV7fSkKfQo=