Skip to content

Commit 0bb8bb4

Browse files
committed
feat: 面向对象封装案例
1 parent d0c64e1 commit 0bb8bb4

File tree

4 files changed

+238
-0
lines changed

4 files changed

+238
-0
lines changed

doc/assets/oop_encapsulation/01.png

25.5 KB
Loading

doc/assets/oop_encapsulation/02.png

46.9 KB
Loading

doc/assets/oop_encapsulation/03.png

36.7 KB
Loading

doc/oop_encapsulation.md

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
# 面向对象封装案例
2+
3+
## 01.封装
4+
5+
1. 封装是面向对象编程的一大特点
6+
2. 面向对象编程的第一步--将属性和方法封装到一个抽象的类中
7+
3. 外界使用类创建对象,然后让对象调用方法
8+
4. 对象方法的细节都被封装在类的内部
9+
10+
## 02.小明爱跑步
11+
12+
1. 小明体重 `75.0` 公斤
13+
2. 小明每次跑步会减肥 `0.5` 公斤
14+
3. 小明每次吃东西体重会增加 `1` 公斤
15+
16+
![封装示例](assets/oop_encapsulation/01.png)
17+
18+
>提示:**在对象的方法内部,是可以直接访问对象的属性**
19+
20+
```python
21+
class Person:
22+
23+
def __init__(self, name, weight) -> None:
24+
25+
# self.属性 = 形参
26+
self.name = name
27+
self.weight = weight
28+
29+
def __str__(self) -> str:
30+
31+
return "我的名字叫%s,体重是%.2f" % (self.name, self.weight)
32+
33+
def run(self):
34+
print("%s 癌跑步,锻炼身体" % self.name)
35+
self.weight -= 0.5
36+
37+
def eat(self):
38+
print("%s 是吃货,吃完这顿再减肥" % self.name)
39+
self.weight += 1
40+
41+
42+
xm = Person("小明", 75)
43+
xm.run()
44+
xm.eat()
45+
46+
print(xm)
47+
```
48+
49+
- 在对象的方法内部,是可以直接访问对象的属性
50+
- 同一个类创建的多个对象之间,属性互不干扰
51+
52+
## 03.摆放家具
53+
54+
1. 房子(House)有户型、总面积和家具名称列表
55+
- 新房子没有任何的家具
56+
2. 家具(HouseItem)有名字和占地面积,其中
57+
- 席梦思(bed)占地 4 平米
58+
- 衣柜(chest)占地 2 平米
59+
- 餐桌(table)占地 1.5 平米
60+
3. 将以上三件家具添加到房子中
61+
4. 打印房子,要求输出:户型、总面积、剩余面积、家具名称列表
62+
63+
![摆放家具](assets/oop_encapsulation/02.png)
64+
65+
**剩余面积**
66+
67+
1. 在创建房子对象时,定义一个剩余面积的属性,初始值和总面积相等
68+
2. 当调用 `add_item` 方法,向房间添加家具时,让剩余面积 -= 家具面积
69+
70+
**添加家具**
71+
72+
1. 判断家具的面积是否超过剩余面积,如果超过,提示不能添加这家家具
73+
2. 将家具名称追加到家具名称列表
74+
3. 用房子的剩余面积 -= 家具面积
75+
76+
```python
77+
class HouseItem:
78+
79+
def __init__(self, name, area) -> None:
80+
81+
self.name = name
82+
self.area = area
83+
84+
def __str__(self) -> str:
85+
86+
return "[%s] 占地 %.2f" % (self.name, self.area)
87+
88+
89+
class House:
90+
91+
def __init__(self, house_type, area) -> None:
92+
93+
# 只有需要外部自定义初始值的属性才需要设置成初始化函数的形参
94+
self.house_type = house_type
95+
self.area = area
96+
# 剩余面积
97+
self.free_area = area
98+
# 家具名称列表
99+
self.item_list = []
100+
101+
def __str__(self) -> str:
102+
103+
# Python 能自动地将一对括号内部地代码连接在一起
104+
return ("户型:%s\n总面积:%.2f[剩余:%.2f]\n家具:%s"
105+
% (self.house_type, self.area,
106+
self.free_area, self.item_list))
107+
108+
def add_item(self, item: HouseItem):
109+
110+
print("要添加 %s" % item)
111+
# 1.判断家具的面积
112+
if item.area > self.free_area:
113+
print("%s 的面积过大,无法添加" % item.name)
114+
return
115+
# 2.将家具的名称添加到列表中
116+
self.item_list.append(item.name)
117+
# 3.计算剩余面积
118+
self.free_area -= item.area
119+
120+
121+
# 1.创建家具
122+
bed = HouseItem("席梦思", 4)
123+
chest = HouseItem("衣柜", 2)
124+
table = HouseItem("餐桌", 1.5)
125+
126+
print(bed)
127+
print(chest)
128+
print(table)
129+
130+
# 2.创建房子对象
131+
my_home = House("两室一厅", 60)
132+
133+
my_home.add_item(bed)
134+
my_home.add_item(chest)
135+
my_home.add_item(table)
136+
137+
print(my_home)
138+
```
139+
140+
**小结**
141+
142+
- 主程序只负责创建房子对象和家具对象
143+
- 让房子对象调用 `add_item` 方法将家具添加到房子中
144+
- 面积计算、剩余面积、家具列表等处理都被封装到房子类的内部
145+
146+
## 04.士兵突击
147+
148+
>一个对象的属性可以是另外一个类创建的对象
149+
150+
### 4.1 需求
151+
152+
1. 士兵许三多有一把 AK47
153+
2. 士兵可以开火
154+
3. 枪能够发射子弹
155+
4. 枪装填子弹--增加子弹数量
156+
157+
![士兵突击](assets/oop_encapsulation/03.png)
158+
159+
### 4.2 开发士兵类
160+
161+
>假设:每一个新兵都没有枪
162+
163+
**定义没有初始值的属性**
164+
165+
在定义属性时,如果不知道设置什么初始值,可以设置为 `None`
166+
167+
- `None` 关键字表示什么都没有
168+
- **表示一个空对象,没有方法和属性,是一个特殊的常量**
169+
- 可以将 `None` 赋值给任何一个变量
170+
171+
**`fire` 方法需求**
172+
173+
1. 判断是否有枪,没有枪没法冲锋
174+
2. 喊一声口号
175+
3. 装填子弹
176+
4. 射击
177+
178+
```python
179+
class Gun:
180+
181+
def __init__(self, model: str) -> None:
182+
183+
# 1.枪的型号
184+
self.model = model
185+
# 2.子弹的数量
186+
self.bullet_count = 0
187+
188+
def add_bullet(self, count: int):
189+
190+
self.bullet_count += count
191+
192+
def shoot(self):
193+
194+
# 1.判断子弹数量
195+
if self.bullet_count <= 0:
196+
print("[%s]没有子弹了" % self.model)
197+
return
198+
# 2.发射子弹
199+
self.bullet_count -= 1
200+
# 3.提示发射信息
201+
print("[%s] 突突突...[%s]" % (self.model, self.bullet_count))
202+
203+
204+
class Soldier:
205+
206+
def __init__(self, name: str) -> None:
207+
208+
# 1.姓名
209+
self.name = name
210+
211+
# 2.枪--新兵没有枪
212+
self.gun = None
213+
214+
def fire(self):
215+
216+
# 1.判断士兵是否有枪
217+
if self.gun == None:
218+
print("[%s]还么有枪..." % self.name)
219+
return
220+
# 2.高喊口号
221+
print("冲啊...[%s]" % self.name)
222+
# 3.装填子弹
223+
self.gun.add_bullet(50)
224+
# 4.发射
225+
self.gun.shoot()
226+
227+
# 1.创建枪对象
228+
ak47 = Gun("AK47")
229+
230+
# ak47.add_bullet(50)
231+
# ak47.shoot()
232+
233+
# 2.创建士兵许三多
234+
xsd = Soldier("许三多")
235+
xsd.gun = ak47
236+
xsd.fire()
237+
print(xsd.gun)
238+
```

0 commit comments

Comments
 (0)