Python-面向对象-封装

150 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

1. 封装

  1. 封装是面向对象编程的一大特点
  2. 面向对象编程的第一步--将属性和方法封装到一个抽象的
  3. 外界使用创建对象,然后让对象调用方法
  4. 对象方法的细节都被封装在类的内部 注意:在对象的方法内部,是可以直接访问对象的属性的!

2. 封装案例演练

2.1 案例一

案例一要求:

  • 小明体重75公斤;
  • 小明每次跑步都会减肥0.5公斤;
  • 小明每次吃东西体重都会增加1公斤。

需求分析(名词提炼法):

  • 类:人类
  • 属性:name(记录小明的名字);体重(记录小明的体重)
  • 方法:run(跑步);eat(吃东西) 代码示例如下所示:首先定义好类,对象与方法。然后,在外部调用封装好的对象方法,即可完成案例需求。
"""
案例要求:
- 小明体重75.0公斤;
- 小明每次跑步都会减肥0.5公斤;
- 小明每次吃东西体重都会增加1公斤。
"""


class Person:
    def __init__(self, name, weight):
        # self.属性 = 形参
        self.name = name
        self.weight = weight

    def __str__(self):
        return "我的名字叫%s 体重是 %.2f 公斤" % (self.name, self.weight)

    def run(self):
        print("%s 爱跑步,跑步锻炼身体" % self.name)
        self.weight -= 0.5

    def eat(self):
        print("%s 是吃货,吃完这顿再减肥" % self.name)
        self.weight += 1


xiaoming = Person("小明", 75.0)
xiaoming.run()
xiaoming.eat()
print(xiaoming)

程序运行结果如下图所示:

image.png

2.2 案例二

案例二要求:

  • 小明和小美都爱跑步
  • 小明体重75.0公斤
  • 小美体重45.0公斤
  • 每次跑步都会减少0.5公斤
  • 每次吃东西都会增加1公斤 注意:
  1. 在对象的方法内部,是可以直接访问对象的属性的
  2. 同一个类创建的多个对象之间,属性互不干扰 代码示例如下所示:在上一个案例的基础上新建一个对象小美,并调用相应的对象方法。
"""
案例要求:
- 小明和小美都爱跑步
- 小明体重75.0公斤
- 小美体重45.0公斤
- 每次跑步都会减少0.5公斤
- 每次吃东西都会增加1公斤
"""


class Person:
    def __init__(self, name, weight):
        # self.属性 = 形参
        self.name = name
        self.weight = weight

    def __str__(self):
        return "我的名字叫%s 体重是 %.2f 公斤" % (self.name, self.weight)

    def run(self):
        print("%s 爱跑步,跑步锻炼身体" % self.name)
        self.weight -= 0.5

    def eat(self):
        print("%s 是吃货,吃完这顿再减肥" % self.name)
        self.weight += 1


xiaoming = Person("小明", 75.0)
xiaoming.run()
xiaoming.eat()
print(xiaoming)

xiaomei = Person("小美", 45)
xiaoming.eat()
xiaomei.run()
print(xiaomei)

程序运行结果如下图所示:可以看出,新增加了对象小美,小美调也用了方法,只影响了小美自身的属性,但是最终输出结果并没有对小明造成影响,从而说明多个对象之间属性互不影响。

image.png

2.3 案例三

案例要求:

  1. 房子(House)有户型、总面积和家具名称列表:新房子没有任何的家具
  2. 家具(HouseItem)有名字和占地面积,其中:
  • 席梦思(bed)占地:4平米
  • 衣柜(chest)占地:2平米
  • 餐桌(table)占地:1.5平米
  1. 将以上三件家具添加到房子中
  2. 打印房子时,要求输出:户型、总面积、剩余面积、家具名称列表 案例分析:
  3. 类:
  • 房子类
  • 家具类
  1. 属性:
  • 房子属性:户型、面积、剩余面积、家具列表
  • 家具属性:家具名,家具占地面积
  1. 方法
  • 房子方法:添加家具

剩余面积:

  1. 在创建房子对象时,定义一个剩余面积的属性,初始值和总面积相等
  2. 当调用add_item方法,向房间添加家具时,让剩余面积 -= 家具面积

注意:本案例应该先开发家具类,原因如下:

  1. 家具简单
  2. 房子要使用到家具,被使用的类,通常应该先开发 代码示例如下所示:
  3. 创建了一个房子类,使用到__init__和__str__两个内置方法
  4. 准备了一个add_item方法准备添加家具
  5. 使用房子类创建了一个房子对象
  6. 让房子对象带哦用了三次add_item方法,将三件家具以实参传递到add_item内部
  7. 判断家具的面积是否超过剩余面积,如果超过,提示不能添加这件家具
  8. 将家具的名称追加到家具名称列表中
  9. 用房子的剩余面积-家具面积
class HouseItem:
    def __init__(self, name, area):
        self.name = name
        self.area = area

    def __str__(self):
        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能够自动的将一对括号内部的代码连接在一起
        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("席梦思", 40)
wardrobe = HouseItem("衣柜", 2)
table = HouseItem("餐桌", 1.5)

print(bed)
print(wardrobe)
print(table)

# 2. 创建房子对象
my_house = House("两室一厅", 60)
my_house.add_item(bed)
my_house.add_item(wardrobe)
my_house.add_item(table)

print(my_house)

程序运行结果如下图所示:

image.png