Python面向对象封装案例

学习地址

目标

  • 封装
  • 小明爱跑步
  • 存放家具

案例

  • 小明爱跑步
需求
  1. 小明体重75.0 Kg
  2. 每次跑步减肥0.5公斤
  3. 每次吃东西增加1公斤
    1
    2
    3
    4
    5
    6
    7
    8
    > Person  
    >  -----------
    > name,weight
    > ------------
    > `__init__`(self,name,weight):
    > `__str__`(self):
    > running(self):  
    > eating(self):
实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Person:
def __init__(self,name,weight):
# self.属性=形参
self.name=name
self.weight=weight
def __str__(self):
return 'my name is %s' %self.name
def eating(self):
self.weight+=1
def running(self):
self.weight-=0.5

xiaoming=Person('小明',75.0)
print(xiaoming)

- - - - - - - - - - -
my name is 小明

案例扩展

同一个类创建的多个对象之间,属性互不干扰

需求
  1. 小明和小美都爱跑步
  2. 小明75.0Kg,小美45.0Kg
  3. running减少0.5Kg
  4. eating增加1Kg
实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Person:
def __init__(self,name,weight):
# self.属性=形参
self.name=name
self.weight=weight
def __str__(self):
return 'my name is %s,my weight is %.1f' %(self.name,self.weight)
def eating(self):
self.weight+=1
def running(self):
self.weight-=0.5

xiaoming=Person('小明',75.0)
xiaomei=Person('小美',45.0)
xiaoming.eating()
xiaoming.running()
print(xiaoming)
print(xiaomei)

- - - - - - - - - - - - - -
my name is 小明,my weight is 75.5
my name is 小美,my weight is 45.0

摆放家具

需求
  1. 房子House有户型,总面积和家具名称列表
    • 新房子没有任何家具
  2. 家具HouseItem有名字和占地面积,其中
    • 席梦思bed占地4 m2
    • 衣柜chest占地2 m2
    • 餐桌table占地1.5 m2
  3. 将以上家具添加到房子中
  4. 打印房子时,要求输出:户型,总面积,剩余面积,家具名称列表

类:House, HouseItem
各自属性:name,area ; house_type, area, free_area, item_list
各自方法:

  • __init__(self,name,area):, __str__(self):
  • __init__(self,house_type,area):, __str__(self):, add_item(self,item):

注意更新房子剩余面积
在开发时,哪个类被用到就先开发哪个类

实现
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
class HouseItem:
def __init__(self,name,area):
self.name=name
self.area=area
def __str__(self):
return 'This is %s , area is %.1f' %(self.name,self.area)


class House:
def __init__(self,type,area):
self.type=type
self.area=area
self.free_area=area
self.item_list=[]
def __str__(self):
# Python会自动将一对括号内部的代码连接在一起
return ('\n户型: %s\n总面积: %.1f(剩余%.1f)\n家具: %s'
%(self.type,self.area,self.free_area,self.item_list))
def add_item(self,item):
print('\n添加家具%s,占地面积%.1f...' %(item.name,item.area))
self.free_area-=item.area
self.item_list.append(item.name)

# 1. 创建家具
bed=HouseItem('ximengsi',4)
chest=HouseItem('衣柜',2)
table=HouseItem('餐桌',2)
print(chest)

# 2. 创建房子对象
my_home=House('两室一厅',120)
print(my_home)
my_home.add_item(bed)
print(my_home)
my_home.add_item(chest)
my_home.add_item(table)
print(my_home)

- - - - - - - - - - - - - -
This is 衣柜 , area is 2.0

户型: 两室一厅
总面积: 120.0(剩余120.0)
家具: []

添加家具ximengsi,占地面积4.0...

户型: 两室一厅
总面积: 120.0(剩余116.0)
家具: ['ximengsi']

添加家具衣柜,占地面积2.0...

添加家具餐桌,占地面积2.0...

户型: 两室一厅
总面积: 120.0(剩余112.0)
家具: ['ximengsi', '衣柜', '餐桌']
进一步改进

在添加家具时,应该考虑到房子剩余面积不小于家具占地面积

1
2
3
4
5
6
7
def add_item(self,item):
print('\n添加家具%s,占地面积%.1f...' %(item.name,item.area))
if self.free_area<item.area:
print('The remaining area is not enough to put down this furniture')
return
self.free_area-=item.area
self.item_list.append(item.name)

小结

主程序只负责创建房子对象和家具对象
其余方法都被封装到类内部

面向对象封装案例

一个对象的属性可以是另一个类所创建的对象

士兵突击
  1. 许三多 有一把 AK47
  2. 士兵可以开火
  3. 枪可以发射子弹
  4. 枪能够装填子弹

这里,枪对象就是士兵的属性
根据上述需求定义枪类和士兵类

关于士兵类

假设:一个新兵没有枪
定义没有初始值的属性
在定义属性时,如果不知道设置什么初始值,可以设置维None

  • None关键字表示空
  • 表示一个空对象,没有方法和属性,是一个特殊的常量
  • 可以将None赋给任意一个变量
实现
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
class Gun:
def __init__(self,model,bullet):
self.model=model # 枪的型号
self.bullet=bullet # 子弹数量
def add_bullet(self,count):
self.bullet+=count
def shoot(self):
if self.bullet<=0:
print("No bullets")
return 0
print('biubiubiu...')
self.bullet-=1


class Soldier:
def __init__(self,name):
self.name=name
self.gun=None # 新兵没有枪
def fire(self):
# 1. 判断是否有枪

if self.gun is None: # 针对None比较时,建议使用is判断,"is"判断引用对象是否一样,“==”判断对象值是否一样
print('%s 还没有枪...' %self.name)
return -1
self.gun.shoot()


# 1. 创建枪对象
ak47=Gun('AK47',36)

# 2. 创建士兵
xusanduo=Soldier('许三多')
xusanduo.gun=ak47
xusanduo.fire()