上一篇文章已经有一个面向对象分装案例了叫“小夏爱跑步”,相对这个摆放家具案例是非常简单的,知识点是回顾初始化方法init和str方法,还有拓展一个知识点——多个的对象属性之间互不干扰。
一、面向对象封装案例——摆放家具需求分析
需求:
1.房子(House)有户型、总面积和家具名称列表
(1)新房子没有任何家具
2. 家具(HouseItem)有名字和占地面积,其中
(1) 席梦思(bed)占地4平方米
(2) 衣柜(chest)占地2.5平方米
(3) 餐桌(table)占地2平方米
3.将以上三件家具添加到房子中
4.打印房子时,要求输出:户型、总面积、剩余面积、家具名称列表
分析:
其中添加家具的添加方法应该定义在房子类中,因为房子初始是没有家具的,使用添加家具的方法add_item(self, item)就可以把家具这个参数item对应的家具名称追加到item_list列表,这样每调用一次方法房子中的家具列表中就会多一个家具,因此应该把添加家具的方法定义在房子中。
剩余面积:
1. 在创建房子对象时,定义一个剩余面积的属性,初始值和总面积相等
2. 当调用add_item方法,向房子添加家具时,让剩余面积-=家具面积
思考一个问题:有两个类,应该先开发哪一个类?
答案:家具类
原因:
1. 家具类简单
2. 房子类要使用到家具,被使用的类,通常应该先开发。不然如果先开发房子类,再开发到家具那一块代码时不得终止再转向来开发家具类这种方法不太明智。
二、开发家具类以及创建家具对象
根据上图中家具类可以看出有2个形参,分别是家具名字和占地面积
代码:
class HouseItem:
# 初始化方法:简化对象的创建
def __init__(self, name, area):
# self.属性 = 形参
self.name = name
self.area = area
# 内置方法__str__(self):简化对象的输出
def __str__(self):
# 这个方法需要注意必须要返回一个字符串
# .2f 表示在遇到小数的时候只保留2位小数
return "[%s] 占地面积是%.2f 平方米" % (self.name, self.area)
# 1. 创建家具对象
bed = HouseItem("席梦思", 4)
chest = HouseItem("衣柜", 2.5)
table = HouseItem("餐桌", 2)
print(bed)
print(chest)
print(table)
执行结果:
三、定义房子类
在上述代码中再添加房子类。看最上面的图,可以看出在房子类中有四个属性,其中房子户型和总面积这两个参数应该由外界传递,而剩余面积free_area怎么办?一个新房子没有任何的家具初始情况下剩余面积就等于总面积,所以剩余面积不需要外界参数传递。第四个参数家具名称列表item_list,新房子一开始没有家具,初始的时候只是一个空列表,所以在准备参数的时候只需要准备两个形参分别是house_type和area。
代码:
class HouseItem:
# 初始化方法:简化对象的创建
def __init__(self, name, area):
# self.属性 = 形参
self.name = name
self.area = area
# 内置方法__str__(self):简化对象的输出
def __str__(self):
# 这个方法需要注意必须要返回一个字符串
# .2f 表示在遇到小数的时候只保留2位小数
return "[%s] 占地面积是%.2f 平方米" % (self.name, self.area)
class House():
def __init__(self, house_type, area):
self.house_type = house_type
self.area = area
# 剩余面积
self.free_area = area # 剩余面积初始值是总面积
# 家具名称列表
self.item_list = [] # 家具列表一开始是一个空列表
def __str__(self):
# python小技巧: Python能够自动的将一对括号内部的代码连接在一起不出错,因为代码过程所以这里用了小括号
return ("户型:%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)
# 1. 创建家具对象
bed = HouseItem("席梦思", 4)
chest = HouseItem("衣柜", 2.5)
table = HouseItem("餐桌", 2)
print(bed)
print(chest)
print(table)
# 2. 创建房子对象
house1 = House("两室一厅", 80)
# 调用添加方法,把家具都添加到新房子中
house1.add_item(bed)
house1.add_item(chest)
house1.add_item(table)
print(house1)
执行结果:
小结:
1. 创建了一个房子类,使用到init和str这两个内置方法
2. 准备了一个add-item方法准备添加家具
3. 使用房子类创建了一个房子对象
4. 让房子对象调用了三次addd_item方法,将三件家具以实参传递到add_item内部
四、完善代码——添加家具方法
需求:
1. 判断家具的面积是否超过剩余面积,如果超过,提示不能添加这件家具
2. 将家具的名称追加到家具列表中
3. 剩余面积 = 当前的房子剩余面积 - 家具面积(房子剩余面积会随着每添加一个家具发生相应的变化)
** 代码:**
class HouseItem:
# 初始化方法:简化对象的创建
def __init__(self, name, area):
# self.属性 = 形参
self.name = name
self.area = area
# 内置方法__str__(self):简化对象的输出
def __str__(self):
# 这个方法需要注意必须要返回一个字符串
# .2f 表示在遇到小数的时候只保留2位小数
return "[%s] 占地面积是%.2f 平方米" % (self.name, self.area)
class House():
def __init__(self, house_type, area):
self.house_type = house_type
self.area = area
# 剩余面积
self.free_area = area # 剩余面积初始值是总面积
# 家具名称列表
self.item_list = [] # 家具列表一开始是一个空列表
def __str__(self):
# python小技巧: Python能够自动的将一对括号内部的代码连接在一起不出错,因为代码过程所以这里用了小括号
return ("户型:%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)
# 1.判断家具的面积
if item.area > self.free_area:
print("%s 的面积太大了,无法添加" % item.name)
return # return关键字可以返回结果也可以不返回结果,下方代码不会被执行
# 2. 将家具添加到家具列表中
self.item_list.append(item.name)
# 3. 计算剩余面积
self.free_area -= item.area
# 1. 创建家具对象
bed = HouseItem("席梦思", 4)
chest = HouseItem("衣柜", 2.5)
table = HouseItem("餐桌", 2)
print(bed)
print(chest)
print(table)
# 2. 创建房子对象
house1 = House("两室一厅", 80)
# 调用添加方法,把家具都添加到新房子中
house1.add_item(bed)
house1.add_item(chest)
house1.add_item(table)
print(house1)
** 执行结果:**
小结:
1. 主程序只负责创建房子对象和家具对象以及调用方法
2. 让房子对象调用add_item方法将家具添加到房子中
3. 面积计算、剩余面积、家具列表等细节处理都被封装到房子类的内部
以上就是关于面向对象案例摆放家具的分析和代码演练,更多Python练习题可以关注Python自学网,不断更新。