- Go provides object-oriented capabilities through struct types and interfaces without classes or inheritance. Structs can have methods defined on them to provide behaviors.
- Go uses composition over inheritance by allowing structs to be embedded within other structs to reuse their fields and methods. This is how interfaces are implemented in Go through embedding.
- Interfaces in Go provide polymorphism by defining a set of common methods. Any type that implements those methods can be used as that interface. This allows for broad interoperability between different types.
- While Go does not have subtyping, embedded fields and methods can be "promoted" to outer structs to reuse functionality, providing some object-oriented capabilities without classes or inheritance.
20. – Wikipedia
A language is usually considered object-based
if it includes the basic capabilities for an
object: identity, properties, and attributes.
A language is considered object-oriented if it
is object-based and also has the capability of
polymorphism and inheritance.
22. Inheritance
• Provides reuse of objects
• Classes are created in hierarchies
• Inheritance lets the structure and
methods in one class pass down the
hierarchy
23. Go’s approach
• Go explicitly avoided inheritance
• Go strictly follows the composition over
inheritance principle
• Composition through embedded types
24. Composition
• Provides reuse of Objects
• One object is declared by including other
objects
• Composition lets the structure and methods
in one class be pulled into another
26. type Person struct {
Name string
Address
}
!
!
type Address struct {
Number string
Street string
City string
State string
Zip string
}
Embedding Types
Inner Type
27. func (a *Address) String() string {
return a.Number+" "+a.Street+"n"+
a.City+", "+a.State+" "+a.Zip+"n"
}
Declaring a Method
30. Promotion
• Promotion looks to see if a single inner type can
satisify the request and “promotes” it
• Embedded fields & methods are “promoted”
• Promotion only occurs during usage, not declaration
• Promoted methods are considered for interface
adherance
31. func (a *Address) String() string {
return a.Number+" "+a.Street+"n"+
a.City+", "+a.State+" "+a.Zip+"n"
}
!
func (p *Person) String() string {
return p.Name + "n" + p.Address.String()
}
Not Overloading
35. Polymorphism
• “The provision of a single interface to
entities of different types”
• Typically implmented via Generics,
Overloading and/or Subtyping
36. Go’s approach
• Go explicitly avoided subtyping &
overloading
• Go does not provide Generics (yet)
• Go’s interface provide polymorphic
capabilities
37. Interfaces
• A list of required methods
• Structural vs Nominal typing
• ‘‘If something can do this, then it can be
used here”
• Convention is call it a Something-er
40. func main() {
r := &Rect{width: 10, height: 5}
x := &Rect{width: 7, height: 10}
rs := &Rects{r, x}
Describe(r)
Describe(x)
Describe(rs)
}
In Action
http://play.golang.org/p/WL77LihUwi
41. –James Gosling (creator of Java)
“If you could do Java over again, what would you
change?” “I’d leave out classes,” he replied. After the
laughter died down, he explained that the real
problem wasn’t classes per se, but rather
implementation inheritance (the extends
relationship). Interface inheritance (the implements
relationship) is preferable. You should avoid
implementation inheritance whenever possible.
45. io.Reader
• Interface
• Read reads up to len(p) bytes into p
• Returns the # of bytes read & any error
• Does not dictate how Read() is implemented
• Used by os.File, bytes.Buffer, net.Conn,
http.Request.Body, loads more
47. io.Writer
• Interface
• Write writes up to len(p) bytes into p
• Returns the # of bytes written & any error
• Does not dictate how Write() is implemented
• Used by os.File, bytes.Buffer, net.Conn,
http.Response.Body, loads more
48. func MarshalGzippedJSON(r io.Reader,
v interface{}) error {
raw, err := gzip.NewReader(r)
if err != nil {
return err
}
return json.NewDecoder(raw).Decode(&v)
}
io.Reader in Action
49. f, err := os.Open("myfile.json.gz")
if err != nil {
log.Fatalln(err)
}
defer f.Close()
m = make(map[string]interface{})
MarshalGzippedJSON(f, &m)
Reading a json.gz file
50. Practical Interoperability
• Gzip.NewReader(io.Reader)
• Works on files, http requests, byte buffers,
network connections, …anything you create
• Nothing special needed in gzip to be able to
do this… Simply call Read(n) and leave the
abstracting to the implementor
53. — Steve Jobs
Simple can be harder than
complex: You have to work hard
to get your thinking clean to
make it simple. But it's worth it
in the end because once you get
there, you can move mountains.