-
Notifications
You must be signed in to change notification settings - Fork 2
/
example1.go
105 lines (89 loc) · 2.41 KB
/
example1.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright 2014 Ardan Studios
//
// All material is licensed under the Apache License Version 2.0, January 2004
// http://www.apache.org/licenses/LICENSE-2.0
// This is an example of using type hierarchies with a OOP pattern.
// This is not something we want to do in Go. Go does not have the
// concept of sub-typing. All types are their own and the concepts of
// base and derived types do not exist in Go. This pattern does not
// provide a good design principle in a Go program.
package main
import "fmt"
// Animal contains all the base fields for animals.
type Animal struct {
Name string
IsMammal bool
}
// Speak provides generic behavior for all animals and
// how they speak.
func (a *Animal) Speak() {
fmt.Printf(
"UGH! My name is %s, it is %t I am a mammal\n",
a.Name,
a.IsMammal,
)
}
// Dog contains everything an Animal is but specific
// attributes that only a Dog has.
type Dog struct {
Animal
PackFactor int
}
// Speak knows how to speak like a dog.
func (d *Dog) Speak() {
fmt.Printf(
"Woof! My name is %s, it is %t I am a mammal with a pack factor of %d.\n",
d.Name,
d.IsMammal,
d.PackFactor,
)
}
// Cat contains everything an Animal is but specific
// attributes that only a Cat has.
type Cat struct {
Animal
ClimbFactor int
}
// Speak knows how to speak like a cat.
func (c *Cat) Speak() {
fmt.Printf(
"Meow! My name is %s, it is %t I am a mammal with a climb factor of %d.\n",
c.Name,
c.IsMammal,
c.ClimbFactor,
)
}
func main() {
// Create a list of Animals that know how to speak.
animals := []Animal{
// Create a Dog by initializing its Animal parts
// and then its specific Dog attributes.
Dog{
Animal: Animal{
Name: "Fido",
IsMammal: true,
},
PackFactor: 5,
},
// Create a Cat by initializing its Animal parts
// and then its specific Cat attributes.
Cat{
Animal: Animal{
Name: "Milo",
IsMammal: true,
},
ClimbFactor: 4,
},
}
// Have the Animals speak.
for _, animal := range animals {
animal.Speak()
}
}
// =============================================================================
// NOTES:
// Smells:
// * The Animal type is providing an abstraction layer of reusable state.
// * The program never needs to create or solely use a value of type Animal.
// * The implementation of the Speak method for the Animal type is a generalization.
// * The Speak method for the Animal type is never going to be called.