笔记来源于b站上的python高级编程视频
目录
封装
案例一、Zhu爱跑步(33也爱跑步)
案例二、摆放家具
创建家具
创建房间以及添加家具
案例三、士兵突击
封装
- 封装是面向对象编程的一大特点
- 面向对象编程的第一步——将属性和方法封装到一个抽象的类中
- 外界使用类创建对象,然后让对象调用方法
- 对象方法的细节都被封装在类的内部
案例一、Zhu爱跑步(33也爱跑步)
同一个类创建的多个对象之间,属性互不干扰;在对象的方法内部,是可以直接访问对象的属性。
需求
- Zhu体重65公斤
- Zhu每次跑步会减肥0.5公斤
- Zhu每次吃东西体重增加1公斤
class Person:
'''人类'''
def __init__(self,name,weight):
self.name = name
self.weight = weight
def __str__(self):
return "i am %s,and my weight is %s kg"%(self.name,self.weight)
def run(self):
print("%s like running"%self.name)
self.weight = self.weight - 0.5
def eat(self):
print("%s like eating"%self.name)
self.weight = self.weight + 1
zhu = Person("Zhu",65)
print(zhu)
zhu.run()
zhu.eat()
print(zhu)
#输出
i am Zhu,and my weight is 65 kg
Zhu like running
Zhu like eating
i am Zhu,and my weight is 65.5 kg
需求
- Zhu和33都爱跑步、吃东西
- 33体重45公斤
- 其他都一样
class Person:
'''人类'''
def __init__(self,name,weight):
self.name = name
self.weight = weight
def __str__(self):
return "i am %s,and my weight is %s kg"%(self.name,self.weight)
def run(self):
print("%s like running"%self.name)
self.weight = self.weight - 0.5
def eat(self):
print("%s like eating"%self.name)
self.weight = self.weight + 1
zhu = Person("Zhu",65)
print(zhu)
zhu.run()
zhu.eat()
print(zhu)
print("\n")
ss = Person("33",45)
print(ss)
ss.run()
ss.eat()
print(ss)
#输出
i am Zhu,and my weight is 65 kg
Zhu like running
Zhu like eating
i am Zhu,and my weight is 65.5 kg
i am 33,and my weight is 45 kg
33 like running
33 like eating
i am 33,and my weight is 45.5 kg
案例二、摆放家具
需求
- 房子(house)有户型、总面积和家具名称列表(新房子没有任何家具)
- 家具(houseitem)有名字和占地面积,其中席梦思(4平米)、衣柜(2平米)、餐桌(1.5平米)
- 将以上三件家具添加到房子中
- 打印房子的时候,要求输出:户型、总面积、剩余面积、家具名称列表
剩余面积
- 在创建房子对象时候,定义一个剩余面积的属性,初始值和总面积相等
- 当调用add_item方法,向房间添加家具时,让剩余面积=总面积-家具面积
因为家具的比较简单,所以房子要用到家具,被使用的类,通常应该先开发
创建家具
创建一个家具类,使用到__init__和__str__两个内置方法
使用家具类创建了三个家具对象,并且输出家具信息
class HouseItem:
def __init__(self,name,area):
'''
:param name:家具名称
:param area:占地面积
'''
self.name = name
self.area = area
def __str__(self):
return "[%s]占地面积%.2f平米"%(self.name,self.area)
bed = HouseItem("席梦思",4)
chest = HouseItem("衣柜",2)
table = HouseItem("餐桌",1.5)
print(bed)
print(chest)
print(table)
#输出
[席梦思]占地面积4.00平米
[衣柜]占地面积2.00平米
[餐桌]占地面积1.50平米
创建房间以及添加家具
创建这个房子类,准备add_item方法准备添加家具,使用房子类创建一个房子对象,让房子对象调用add_item方法,将家具以实参传递到add_item内部
主程序只负责创建房子对象和家具对象,让房子对象调用add_item方法将家具添加到房子中,面积计算、剩余面积、家具列表等处理被封装到房子类的内部
class House:
def __init__(self,house_type,area):
'''
:param house_type:户型
:parma area:总面积
'''
self.house_type= house_type
self.area = area
#剩余面积默认和总面积一致
self.free_area = area
#默认没有任何的家具
self.item_list = []
def __str__(self):
return ("\n户型:%s\n总面积:%.2f[剩余:%.2f]\n家具:%s"
%(self.house_type, self.area, self.free_area, self.item_list))
def add_item(self,item):
print("要添加%s"%item)
#判断家具面积是否大于剩余面积
if item.area > self.free_area:
print("%s的面积太大,不能添加到房子中"%item.name)
else:
self.item_list.append(item.name)
self.free_area = self.free_area - item.area
class HouseItem:
def __init__(self,name,area):
'''
:param name:家具名称
:param area:占地面积
'''
self.name = name
self.area = area
def __str__(self):
return "[%s]占地面积%.2f平米"%(self.name,self.area)
bed = HouseItem("席梦思",4)
chest = HouseItem("衣柜",2)
table = HouseItem("餐桌",1.5)
print(bed,chest,table)
house = House("八室两厅",120)
for num in range(4):
house.add_item(bed)
for num in range(4):
house.add_item(chest)
house.add_item(table)
print(house)
#输出
[席梦思]占地面积4.00平米 [衣柜]占地面积2.00平米 [餐桌]占地面积1.50平米
要添加[席梦思]占地面积4.00平米
要添加[席梦思]占地面积4.00平米
要添加[席梦思]占地面积4.00平米
要添加[席梦思]占地面积4.00平米
要添加[衣柜]占地面积2.00平米
要添加[衣柜]占地面积2.00平米
要添加[衣柜]占地面积2.00平米
要添加[衣柜]占地面积2.00平米
要添加[餐桌]占地面积1.50平米
户型:八室两厅
总面积:120.00[剩余:94.50]
家具:['席梦思', '席梦思', '席梦思', '席梦思', '衣柜', '衣柜', '衣柜', '衣柜', '餐桌']
一个对象的属性可以是另外一个类创建的对象
案例三、士兵突击
需求
- 士兵许三多有一把95
- 士兵可以开火
- 枪可以发射子弹——子弹变少
- 枪可以装子弹——增加子弹数量
class Gun:
def __init__(self,model):
#枪的型号
self.model = model
#子弹数量
self.bullet_count = 0
def add_bullet(self,count):
self.bullet_count = self.bullet_count + count
def shoot(self):
#判断是否还有子弹
if self.bullet_count <= 0:
print("没有子弹了")
else:
self.bullet_count = self.bullet_count -1
print("%s还可发射子弹[%d]"%(self.model,self.bullet_count))
class soldier:
def __init__(self,name):
#姓名
self.name = name
#枪(士兵一开始没有枪 None表示什么都没有)
self.gun = None
def fire(self):
#判断士兵有没有枪
if self.gun is None:
print("[%s]还没有枪..."%self.name)
else:
print("[%s]gogogo!"%self.name)
if self.gun.bullet_count <=10:
self.gun.add_bullet(50)
self.gun.shoot()
#创建枪对象
a95 = Gun("95-a")
#创建士兵的对象
zhu = soldier("zhuzhu")
zhu.gun = a95
zhu.fire()
ss = soldier("33")
ss.fire()
#输出
[zhuzhu]gogogo!
95-a还可发射子弹[49]
[33]还没有枪...
在定义属性时,如果不知道设置什么初始值,可以设置为None,这个是一个空对象,表示什么都没有,没有属性和方法,是一个特殊的常量,可以将None赋值给任何一个变量。对于None的比较时,建议使用is判断,表示引用的对象是否为同一个,而==通常表示两个引用变量的值是否相等