1
1
2
2
# 私有的和受保护的属性和方法
3
3
4
- 面向对象编程最重要的原则之一—— 划分出外部接口和内部接口。
4
+ 面向对象编程最重要的原则之一 —— 划分出外部接口和内部接口。
5
5
6
6
在开发比 “hello world” 应用更复杂的东西时,这是“必须”的做法。
7
7
11
11
12
12
## 一个真实的例子
13
13
14
- 例如咖啡机。从外面看很简单:一个按钮,一个显示器,几个洞……当然,结果就是—— 很棒的咖啡!:)
14
+ 例如咖啡机。从外面看很简单:一个按钮,一个显示器,几个洞……当然,结果就是 —— 很棒的咖啡!:)
15
15
16
16
![ ] ( coffee.jpg )
17
17
21
21
22
22
有很多细节。但我们可以在不了解的情况下使用它。
23
23
24
- 咖啡机非常可靠,不是吗?我们可以使用好几年,只有在出现问题时—— 进行维修。
24
+ 咖啡机非常可靠,不是吗?我们可以使用好几年,只有在出现问题时 —— 进行维修。
25
25
26
- 咖啡机的可靠性和简洁性的秘诀—— 所有细节都经过精心调整并 * 隐藏 * 在内部。
26
+ 咖啡机的可靠性和简洁性的秘诀 —— 所有细节都经过精心调整并 ** 隐藏 * * 在内部。
27
27
28
28
如果我们从咖啡机上取下保护盖,那么使用它将会复杂得多(要按哪里?),并且危险(会触电)。
29
29
35
35
36
36
在面向对象的编程中,属性和方法分为两组:
37
37
38
- - * 内部接口* —— 可以通过类的其他方法访问,但不能从外部访问的方法和属性。
39
- - * 外部接口* —— 也可从类的外部访问的方法和属性。
38
+ - ** 内部接口* * —— 可以通过类的其他方法访问,但不能从外部访问的方法和属性。
39
+ - ** 外部接口* * —— 也可从类的外部访问的方法和属性。
40
40
41
- 如果我们继续用咖啡机进行类比—— 内部隐藏的内容:锅炉管,加热元件等—— 是其内部的接口。
41
+ 如果我们继续用咖啡机进行类比 —— 内部隐藏的内容:锅炉管,加热元件等 —— 是其内部的接口。
42
42
43
43
内部接口用于对象,它的细节相互使用。例如,锅炉管连接到加热元件。
44
44
48
48
49
49
这是个概括的介绍。
50
50
51
- 在 JavaScript 中,有两种类型的对象字段(属性和成员 ):
51
+ 在 JavaScript 中,有两种类型的对象字段(属性和方法 ):
52
52
53
53
- 公共的:可从任何地方访问。它们包含外部接口。直到现在我们只使用公共属性和方法。
54
54
- 私有的:只能从类的内部访问。这些用于内部接口。
55
55
56
56
在许多其他语言中,还存在“受保护”的字段:只能从类的内部访问和扩展它们(类似私有的,但是加上了向继承的类的访问)。它们对内部接口也很有用。它们在某种意义上比私有的属性和方法更广泛,因为我们通常希望继承类来获得正确执行扩展的访问权限。
57
57
58
- 受保护的字段不是在语言级别的 Javascript 中实现的 ,但实际上它们非常方便,因此它们是模拟(这里求校对)的 。
58
+ 受保护的字段不是在 Javascript 语言级别上实现的 ,但实际上它们非常方便,因为它们是在 Javascript 中模拟的类定义语法 。
59
59
60
60
现在,我们将使用所有这些类型的属性在 Javascript 中制作咖啡机。咖啡机有很多细节,我们不会对它们进行全面模拟以保持简洁(尽管我们可以)。
61
61
62
- ## 受保护的 “waterAmount”
62
+ ## 受保护的“waterAmount”
63
63
64
64
让我们先做一个简单的咖啡机类:
65
65
@@ -117,9 +117,9 @@ let coffeeMachine = new CoffeeMachine(100);
117
117
coffeeMachine .waterAmount = - 10 ; // Error: Negative water
118
118
```
119
119
120
- 现在访问受到控制,因此将水量设置为小于零的数失败了 。
120
+ 现在访问受到控制,因此将水量设置为小于零的数将会失败 。
121
121
122
- ## 只读的 “power”
122
+ ## 只读的“power”
123
123
124
124
对于 ` power ` 属性,让我们将它设为只读的。有时候一个属性必须仅在创建时设置,然后不再修改。
125
125
@@ -144,12 +144,12 @@ class CoffeeMachine {
144
144
// 创建咖啡机
145
145
let coffeeMachine = new CoffeeMachine (100 );
146
146
147
- alert (` Power is: ${ coffeeMachine .power } W` ); // 功率是100W
147
+ alert (` Power is: ${ coffeeMachine .power } W` ); // 功率是:100W
148
148
149
149
coffeeMachine .power = 25 ; // Error (no setter)
150
150
```
151
151
152
- ```` smart header="Getter/setter 功能 "
152
+ ```` smart header="Getter/setter 函数 "
153
153
这里我们使用 getter/setter 语法。
154
154
155
155
但大多数时候首选 `get.../set...` 函数,像这样:
@@ -182,7 +182,7 @@ new CoffeeMachine().setWaterAmount(100);
182
182
所以受保护的字段是自然可继承的。不像我们接下来将看到的私有字段。
183
183
```
184
184
185
- ## 私有的 “#waterLimit”
185
+ ## 私有的“#waterLimit”
186
186
187
187
[ recent browser=none]
188
188
@@ -205,19 +205,6 @@ class CoffeeMachine {
205
205
}
206
206
*/ ! *
207
207
208
- _waterAmount = 0 ;
209
-
210
- set waterAmount (value ) {
211
- * ! *
212
- this .#checkWater (value);
213
- */ ! *
214
- this ._waterAmount = value;
215
- }
216
-
217
- get waterAmount () {
218
- return this ._waterAmount ;
219
- }
220
-
221
208
}
222
209
223
210
let coffeeMachine = new CoffeeMachine ();
@@ -264,7 +251,7 @@ alert(machine.#waterAmount); // Error
264
251
class MegaCoffeeMachine extends CoffeeMachine () {
265
252
method () {
266
253
* ! *
267
- alert ( this .#waterAmount ); // Error: can only access from CoffeeMachine
254
+ alert ( this .#waterAmount ); // 错误:只能从 CoffeeMachine 中访问
268
255
*/ ! *
269
256
}
270
257
}
@@ -275,7 +262,7 @@ class MegaCoffeeMachine extends CoffeeMachine() {
275
262
```` warn header="私有字段不能通过 this[name] 访问"
276
263
私有字段很特别。
277
264
278
- 如我们所知,通常我们可以使用 this[name] 访问字段:
265
+ 如我们所知,通常我们可以使用 ` this[name]` 访问字段:
279
266
280
267
```js
281
268
class User {
@@ -297,13 +284,13 @@ class User {
297
284
它具有以下优点:
298
285
299
286
保护用户,使他们不会误伤自己
300
- : 想象一下,有一群开发人员使用咖啡机。它是由 “Best CoffeeMachine” 公司制造的,工作正常,但保护盖被拿走了。因此内部接口暴露了出来。
287
+ : 想象一下,有一群开发人员使用咖啡机。它是由“Best CoffeeMachine”公司制造的,工作正常,但保护盖被拿走了。因此内部接口暴露了出来。
301
288
302
- 所有的开发人员都是文明的—— 他们按照预期使用咖啡机。但其中一个人,约翰,被认为是最聪明的,并且决定让他在咖啡机内部做一些调整。然而咖啡机两天后就坏了。
289
+ 所有的开发人员都是文明的 —— 他们按照预期使用咖啡机。但其中一个人,约翰,被认为是最聪明的,并且决定让他在咖啡机内部做一些调整。然而咖啡机两天后就坏了。
303
290
304
- 这肯定不是约翰的错,而是那个取下保护套并让约翰执行自己操作的人 。
291
+ 这肯定不是约翰的错,而是那个取下保护套并让约翰执行自己操作的人的错 。
305
292
306
- 编程也一样。如果一个类的使用者想要改变那些本不打算从外部改变的东西—— 后果是不可预测的。
293
+ 编程也一样。如果一个类的使用者想要改变那些本不打算从外部改变的东西 —— 后果是不可预测的。
307
294
308
295
可支持的
309
296
: 编程的情况比现实生活中的咖啡机更复杂,因为我们不只是购买一次。代码不断经历着发展和改进。
@@ -321,7 +308,7 @@ class User {
321
308
322
309
**隐藏实施细节时总是很方便,并且提供了一个简单的,记录详细的外部接口。**
323
310
324
- 为了隐藏内部接口,我们使用受保护的或公共的属性 :
311
+ 为了隐藏内部接口,我们使用受保护的或私有的属性 :
325
312
326
313
- 受保护的字段以 ` _ ` 开头。这是一个众所周知的惯例,没有在语言层面强制执行。程序员只应该通过它的类和它继承的类中访问以 ` _ ` 开头的字段。
327
314
- 私有字段以 ` # ` 开头。JavaScript 确保我们只能访问类中的内容。
0 commit comments