Skip to content

Commit 8560bf4

Browse files
committed
feat:面向对象进阶
1 parent 0cfcf93 commit 8560bf4

File tree

1 file changed

+64
-7
lines changed

1 file changed

+64
-7
lines changed

doc/oop_advanced.md

+64-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
- 类属性和实例属性
77
- 类方法和静态方法
88

9-
# . 面向对象三大特性
9+
# 1. 面向对象三大特性
1010

1111
- 封装
1212
- 将属性和方法书写到类的里面的操作即为封装
@@ -19,7 +19,7 @@
1919

2020

2121

22-
# . 多态
22+
# 2. 多态
2323

2424
## 2.1 了解多态
2525

@@ -65,7 +65,7 @@ daqiu.work_with_dog(dd)
6565

6666

6767

68-
# . 类属性和实例属性
68+
# 3. 类属性和实例属性
6969

7070
## 3.1 类属性
7171

@@ -140,7 +140,7 @@ wangcai.info_print() # 5
140140

141141

142142

143-
# . 类方法和静态方法
143+
# 4. 类方法和静态方法
144144

145145
## 4.1 类方法
146146

@@ -178,7 +178,7 @@ print(result) # 10
178178
- 需要通过装饰器`@staticmethod`来进行修饰,**静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)**
179179
- 静态方法 也能够通过 **实例对象****类对象** 去访问。
180180

181-
## 4.2.2 静态方法使用场景
181+
### 4.2.2 静态方法使用场景
182182

183183
- 当方法中 **既不需要使用实例对象**(如实例对象,实例属性),**也不需要使用类对象** (如类属性、类方法、创建实例等)时,定义静态方法
184184
- **取消不需要的参数传递**,有利于 **减少不必要的内存占用和性能消耗**
@@ -196,9 +196,64 @@ wangcai.info_print()
196196
Dog.info_print()
197197
```
198198

199+
## 5. 可见性和属性装饰器
199200

201+
在很多面向对象编程语言中,对象的属性通常会被设置为私有(private)或受保护(protected)的成员,简单的说就是不允许直接访问这些属性;对象的方法通常都是公开的(public),因为公开的方法是对象能够接受的消息,也是对象暴露给外界的调用接口,这就是所谓的访问可见性。在 Python 中,可以通过给对象属性名添加前缀下划线的方式来说明属性的访问可见性,例如,可以用`__name`表示一个私有属性,`_name`表示一个受保护属性,代码如下所示。
200202

201-
# 五. 总结
203+
```python
204+
class Student:
205+
206+
def __init__(self, name, age):
207+
self.__name = name
208+
self.__age = age
209+
210+
def study(self, course_name):
211+
print(f'{self.__name}正在学习{course_name}.')
212+
213+
214+
stu = Student('王大锤', 20)
215+
stu.study('Python程序设计')
216+
print(stu.__name) # AttributeError: 'Student' object has no attribute '__name'
217+
```
218+
219+
上面代码的最后一行会引发`AttributeError`(属性错误)异常,异常消息为:`'Student' object has no attribute '__name'`。由此可见,以`__`开头的属性`__name`相当于是私有的,在类的外面无法直接访问,但是类里面的`study`方法中可以通过`self.__name`访问该属性。需要说明的是,大多数使用 Python 语言的人在定义类时,通常不会选择让对象的属性私有或受保护,正如有一句名言说的:“**We are all consenting adults here**”(大家都是成年人),成年人可以为自己的行为负责,而不需要通过 Python 语言本身来限制访问可见性。事实上,大多数的程序员都认为**开放比封闭要好**,把对象的属性私有化并非必不可少的东西,所以 Python 语言并没有从语义上做出最严格的限定,也就是说上面的代码如果你愿意,用`stu._Student__name`的方式仍然可以访问到私有属性`__name`,有兴趣的读者可以自己试一试。
220+
221+
## 6. 动态属性
222+
223+
Python 语言属于动态语言,维基百科对动态语言的解释是:“在运行时可以改变其结构的语言,例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化”。动态语言非常灵活,目前流行的 Python 和 JavaScript 都是动态语言,除此之外,诸如 PHP、Ruby 等也都属于动态语言,而 C、C++ 等语言则不属于动态语言。
224+
225+
在 Python 中,我们可以动态为对象添加属性,这是 Python 作为动态类型语言的一项特权,代码如下所示。需要提醒大家的是,对象的方法其实本质上也是对象的属性,如果给对象发送一个无法接收的消息,引发的异常仍然是`AttributeError`
226+
227+
```python
228+
class Student:
229+
230+
def __init__(self, name, age):
231+
self.name = name
232+
self.age = age
233+
234+
235+
stu = Student('王大锤', 20)
236+
stu.sex = '' # 给学生对象动态添加sex属性
237+
```
238+
239+
如果不希望在使用对象时动态的为对象添加属性,可以使用 Python 语言中的`__slots__`魔法。对于`Student`类来说,可以在类中指定`__slots__ = ('name', 'age')`,这样`Student`类的对象只能有`name``age`属性,如果想动态添加其他属性将会引发异常,代码如下所示。
240+
241+
```python
242+
class Student:
243+
__slots__ = ('name', 'age')
244+
245+
def __init__(self, name, age):
246+
self.name = name
247+
self.age = age
248+
249+
250+
stu = Student('王大锤', 20)
251+
# AttributeError: 'Student' object has no attribute 'sex'
252+
stu.sex = ''
253+
```
254+
255+
256+
# 7. 总结
202257

203258
- 面向对象三大特性
204259
- 封装
@@ -221,4 +276,6 @@ def xx():
221276
@staticmethod
222277
def xx():
223278
代码
224-
```
279+
```
280+
281+
Python 是动态类型语言,Python 中的对象可以动态的添加属性,对象的方法其实也是属性,只不过和该属性对应的是一个可以调用的函数。在面向对象的世界中,**一切皆为对象**,我们定义的类也是对象,所以**类也可以接收消息**,对应的方法是类方法或静态方法。通过继承,我们**可以从已有的类创建新类**,实现对已有类代码的复用。

0 commit comments

Comments
 (0)