Skip to content

Commit 367ff44

Browse files
committed
improving this chapter
1 parent cf5a398 commit 367ff44

File tree

1 file changed

+51
-47
lines changed

1 file changed

+51
-47
lines changed

en/02.5.md

+51-47
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Object-oriented
22

3-
We talked about functions and structs in the last two sections, but did you ever consider using functions as fields of a struct? In this section, I will introduce you to another form of function that has a receiver, which is called `method`.
3+
We talked about functions and structs in the last two sections, but did you ever consider using functions as fields of a struct? In this section, I will introduce you to another form of function that has a receiver, which is called a `method`.
44

55
## method
66

@@ -25,7 +25,7 @@ func main() {
2525
fmt.Println("Area of r2 is: ", area(r2))
2626
}
2727

28-
```
28+
```
2929
The above example can calculate a rectangle's area. We use the function called `area`, but it's not a method of the rectangle struct (like class methods in classic object-oriented languages). The function and struct are two independent things as you may notice.
3030

3131
It's not a problem so far. However, if you also have to calculate the area of a circle, square, pentagon, or any other kind of shape, you are going to need to add additional functions with very similar names.
@@ -36,18 +36,18 @@ Figure 2.8 Relationship between function and struct
3636

3737
Obviously that's not cool. Also, the area should really be the property of a circle or rectangle.
3838

39-
For those reasons, we have the `method` concept. `method` is affiliated with type. It has the same syntax as functions do except for an additional parameter after the `func` keyword called the `receiver`, which is the main body of that method.
39+
This is where a `method` comes to play. The `method` is a function affiliated with a type. It has similar syntax as function except, after the `func` keyword has a parameter called the `receiver`, which is the main body of that method.
4040

41-
Using the same example, `Rectangle.area()` belongs directly to rectangle, instead of as a peripheral function. More specifically, `length`, `width` and `area()` all belong to rectangle.
41+
Using the same example, `Rectangle.Area()` belongs directly to rectangle, instead of as a peripheral function. More specifically, `length`, `width` and `Area()` all belong to rectangle.
4242

4343
As Rob Pike said.
4444

4545
"A method is a function with an implicit first argument, called a receiver."
46-
46+
4747
Syntax of method.
4848
```Go
4949
func (r ReceiverType) funcName(parameters) (results)
50-
```
50+
```
5151
Let's change our example using `method` instead.
5252
```Go
5353
package main
@@ -57,46 +57,48 @@ import (
5757
"math"
5858
)
5959

60-
type Rectangle struct {
61-
width, height float64
62-
}
63-
6460
type Circle struct {
6561
radius float64
6662
}
6763

68-
func (r Rectangle) area() float64 {
69-
return r.width * r.height
64+
type Rectangle struct {
65+
width, height float64
7066
}
7167

72-
func (c Circle) area() float64 {
68+
// method
69+
func (c Circle) Area() float64 {
7370
return c.radius * c.radius * math.Pi
7471
}
7572

73+
// method
74+
func (r Rectangle) Area() float64 {
75+
return r.width * r.height
76+
}
77+
7678
func main() {
77-
r1 := Rectangle{12, 2}
78-
r2 := Rectangle{9, 4}
7979
c1 := Circle{10}
8080
c2 := Circle{25}
81+
r1 := Rectangle{9, 4}
82+
r2 := Rectangle{12, 2}
8183

82-
fmt.Println("Area of r1 is: ", r1.area())
83-
fmt.Println("Area of r2 is: ", r2.area())
84-
fmt.Println("Area of c1 is: ", c1.area())
85-
fmt.Println("Area of c2 is: ", c2.area())
84+
fmt.Println("Area of c1 is: ", c1.Area())
85+
fmt.Println("Area of c2 is: ", c2.Area())
86+
fmt.Println("Area of r1 is: ", r1.Area())
87+
fmt.Println("Area of r2 is: ", r2.Area())
8688
}
89+
```
8790

88-
```
8991
Notes for using methods.
9092

9193
- If the name of methods are the same but they don't share the same receivers, they are not the same.
9294
- Methods are able to access fields within receivers.
93-
- Use `.` to call a method in the struct, the same way fields are called.
95+
- Use `.` to call a method in the struct, the same way fields are called.
9496

9597
![](images/2.5.shapes_func_with_receiver_cp.png?raw=true)
9698

9799
Figure 2.9 Methods are different in different structs
98100

99-
In the example above, the area() methods belong to both Rectangle and Circle respectively, so the receivers are Rectangle and Circle.
101+
In the example above, the Area() methods belong to both Rectangle and Circle respectively, so the receivers are Rectangle and Circle.
100102

101103
One thing that's worth noting is that the method with a dotted line means the receiver is passed by value, not by reference. The difference between them is that a method can change its receiver's values when the receiver is passed by reference, and it gets a copy of the receiver when the receiver is passed by value.
102104

@@ -105,13 +107,12 @@ Can the receiver only be a struct? Of course not. Any type can be the receiver o
105107
Use the following format to define a customized type.
106108
```Go
107109
type typeName typeLiteral
108-
```
110+
```
109111
Examples of customized types:
110-
```Go
111-
type ages int
112112

113+
```Go
114+
type age int
113115
type money float32
114-
115116
type months map[string]int
116117

117118
m := months {
@@ -120,7 +121,8 @@ m := months {
120121
...
121122
"December":31,
122123
}
123-
```
124+
```
125+
124126
I hope that you know how to use customized types now. Similar to `typedef` in C, we use `ages` to substitute `int` in the above example.
125127

126128
Let's get back to talking about `method`.
@@ -139,23 +141,24 @@ const (
139141
YELLOW
140142
)
141143

142-
type Color byte
143-
144144
type Box struct {
145145
width, height, depth float64
146-
color Color
146+
color Color
147147
}
148-
148+
type Color byte
149149
type BoxList []Box //a slice of boxes
150150

151+
// method
151152
func (b Box) Volume() float64 {
152153
return b.width * b.height * b.depth
153154
}
154155

156+
// method with a pointer receiver
155157
func (b *Box) SetColor(c Color) {
156158
b.color = c
157159
}
158160

161+
// method
159162
func (bl BoxList) BiggestsColor() Color {
160163
v := 0.00
161164
k := Color(WHITE)
@@ -168,12 +171,14 @@ func (bl BoxList) BiggestsColor() Color {
168171
return k
169172
}
170173

174+
// method
171175
func (bl BoxList) PaintItBlack() {
172176
for i, _ := range bl {
173177
bl[i].SetColor(BLACK)
174178
}
175179
}
176180

181+
// method
177182
func (c Color) String() string {
178183
strings := []string{"WHITE", "BLACK", "BLUE", "RED", "YELLOW"}
179184
return strings[c]
@@ -194,14 +199,14 @@ func main() {
194199
fmt.Println("The color of the last one is", boxes[len(boxes)-1].color.String())
195200
fmt.Println("The biggest one is", boxes.BiggestsColor().String())
196201

197-
fmt.Println("Let's paint them all black")
202+
// Let's paint them all black
198203
boxes.PaintItBlack()
199-
fmt.Println("The color of the second one is", boxes[1].color.String())
200204

205+
fmt.Println("The color of the second one is", boxes[1].color.String())
201206
fmt.Println("Obviously, now, the biggest one is", boxes.BiggestsColor().String())
202207
}
208+
```
203209

204-
```
205210
We define some constants and customized types.
206211

207212
- Use `Color` as alias of `byte`.
@@ -210,11 +215,11 @@ We define some constants and customized types.
210215

211216
Then we defined some methods for our customized types.
212217

213-
- Volume() uses Box as its receiver and returns the volume of Box.
214-
- SetColor(c Color) changes Box's color.
215-
- BiggestsColor() returns the color which has the biggest volume.
216-
- PaintItBlack() sets color for all Box in BoxList to black.
217-
- String() use Color as its receiver, returns the string format of color name.
218+
- `Volume()` uses Box as its receiver and returns the volume of Box.
219+
- `SetColor(`c Color) changes Box's color.
220+
- `BiggestsColor()` returns the color which has the biggest volume.
221+
- `PaintItBlack()` sets color for all Box in BoxList to black.
222+
- `String()` use Color as its receiver, returns the string format of color name.
218223

219224
Is it much clearer when we use words to describe our requirements? We often write our requirements before we start coding.
220225

@@ -224,13 +229,13 @@ Let's take a look at `SetColor` method. Its receiver is a pointer of Box. Yes, y
224229

225230
If we see that a receiver is the first argument of a method, it's not hard to understand how it works.
226231

227-
You might be asking why we aren't using `(*b).Color=c` instead of `b.Color=c` in the SetColor() method. Either one is OK here because Go knows how to interpret the assignment. Do you think Go is more fascinating now?
232+
You might be asking why we aren't using `(*b).Color=c` instead of `b.Color=c` in the `SetColor()` method. Either one is OK here because Go knows how to interpret the assignment. Do you think Go is more fascinating now?
228233

229234
You may also be asking whether we should use `(&bl[i]).SetColor(BLACK)` in `PaintItBlack` because we pass a pointer to `SetColor`. Again, either one is OK because Go knows how to interpret it!
230235

231236
### Inheritance of method
232237

233-
We learned about inheritance of fields in the last section. Similarly, we also have method inheritance in Go. If an anonymous field has methods, then the struct that contains the field will have all the methods from it as well.
238+
We learned about inheritance of fields in the last section. Similarly, we also have method inheritance in Go. If an anonymous field has methods, then the struct that contains the field will have all the methods from it as well.
234239
```Go
235240
package main
236241

@@ -258,13 +263,12 @@ func (h *Human) SayHi() {
258263
}
259264

260265
func main() {
261-
mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
262266
sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}
267+
mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
263268

264-
mark.SayHi()
265269
sam.SayHi()
270+
mark.SayHi()
266271
}
267-
268272
```
269273
### Method overload
270274

@@ -300,14 +304,14 @@ func (e *Employee) SayHi() {
300304
}
301305

302306
func main() {
303-
mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
304307
sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}
308+
mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
305309

306-
mark.SayHi()
307310
sam.SayHi()
311+
mark.SayHi()
308312
}
309313

310-
```
314+
```
311315
You are able to write an Object-oriented program now, and methods use rule of capital letter to decide whether public or private as well.
312316

313317
## Links

0 commit comments

Comments
 (0)