12 面向对象封装案例

12 面向对象封装案例

01.封装
  1. 封装是面向对象编程的一大特点
  2. 面向对象编程的第一步——将属性和方法封装到一个抽象的类中
  3. 外界使用类创建对象,然后让对象调用方法
  4. 对象方法的细节都被封装在类的内部

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

02.小明爱跑步

需求

1.小明体重75.0公斤

2.小明每次跑步会减肥0.5公斤

3.小明每次吃东西体重增加1公斤

代码实现

提示:在对象方法的内部,是可以直接访问对象的属性的!

class Persion:
    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("跑完步")
        self.weight -= 0.5

    def eat(self):
        print("吃完东西")
        self.weight += 1


xm = Persion("小明", 75.0)
xm.run()
xm.eat()
print(xm)
03 扩展—小红也爱跑步

需求

  1. 小明和小红都爱跑步
  2. 小明体重 75.0 公斤
  3. 小红体重 45.0 公斤
  4. 每次跑步都会减少 0.5 公斤
  5. 每次吃东西都会增加 1 公斤

提示:

  1. 在对象的方法内部,是可以直接访问对象的属性的
  2. 同一个类创建的多个对象之间,属性互不干扰
class Persion:
    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("跑完步")
        self.weight -= 0.5

    def eat(self):
        print("吃完东西")
        self.weight += 1


xm = Persion("小明", 75.0)
xm.run()
xm.eat()
print(xm)
xh = Persion("小红", 45.0)
xh.run()
xh.eat()
print(xh)
04 摆放家具

需求:

  1. 房子有户型(House),总面积和家具名称列表

    • 新房子没有任何的家具
  2. 家具(HouseItem)有名字,和占地面积,其中

    • 席梦恩(bed)占地 4 平米
    • 衣柜(chest)占地 2 平米
    • 餐桌(table) 占地 1.5 平米
  3. 将以上三件家具添加到房子中

    • 判断家具面积是否超过剩余面积,如果超过提示不能添加这件家具
    • 将家具的名称追加到家具名称列表中
  4. 打印房子时,要求输出:户型、总面积、剩余面积、家具名称列表

    • 用房子的剩余面积 - 家具的面积
# 家具类
HouseItem:			
name
area
__init__(self, name, area):
__str__(self):

# 房子类
House:
house_type
area
free_area
item_list
__init__(self, house_type, area):
__str__(self):
add_item(self, item): # 添加家具

完整代码:

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):
        return ("户型:%s\n总面积:%.2f\n剩余面积:%.2f\n家具列表:%s"
                % (self.house_type, self.area, self.free_area, self.item_list))

    def add_item(self, item):
        # 判断家具的面积
        if item.area > self.free_area:
            print("%s面过太大,无法添加" % item.name)
            return

        # 将家具名称添加到家具列表
        self.item_list.append(item.name)

        # 计算剩余面积
        self.free_area -= item.area


bed = HouseItem("席梦思", 4)
chest = HouseItem("衣柜", 2)
table = HouseItem("餐桌", 1.5)
print(bed)
print(chest)
print(table)

my_house = House("两室一厅", 60)
my_house.add_item(bed)
my_house.add_item(chest)
my_house.add_item(table)
print(my_house)

小结:

  • 主程序只负责创建房子对象和家具对象
  • 让房子对象调用 add_item 方法将家具添加到房子中
  • 面积计算、剩余面积、家具列表等处理都被封装到房子类的内部
05 士兵突击

需求:

  1. 士兵 许三多 有一把 AK47
  2. 士兵可以开火
  3. 抢可以发射子弹
  4. 抢装填子弹 —— 增加子弹数量
类:Soldier				  GUN		
属性:name					model	
  	 gun				  bullet_count			
__init__(self):			  __init__(self, model):				
fire(self):				  add_bullet(self, count)
						  shoot(self):

枪类代码

class GUN:
    def __init__(self, mode):
        self.mode = mode
        self.bullet_count = 0

    def add_bullet(self, count):
      self.bullet_count += count

    def shoot(self):
        # 判断子弹的数量
        if self.bullet_count <= 0:
            print("[%s] 没有子弹了。。。" % self.mode)
            return

        # 发射子弹计算剩余子弹
        self.bullet_count -= 1

        # 提示用户信息
        print("[%s] 发射成功。。。[%d]" % (self.mode, self.bullet_count))


ak47 = GUN("ak47")
ak47.add_bullet(3)
ak47.shoot()

士兵类开发

假设每一个新兵都没有枪

定义没有初始值的属性

在定义属性时,如果不知道设置什么初始值,可以设置为 None

  • None 关键字表示什么都没有
  • 表示一个空对象,没有方法和属性,是一个特殊的变量
  • 可以将None 复制给任何一个变量

fire 方法需求

  • 1> 判断是否有枪,没有强没法冲锋
  • 2> 喊一声口号
  • 3> 装填子弹
  • 4> 射击

完整代码:

class GUN:
    def __init__(self, mode):
        self.mode = mode
        self.bullet_count = 0

    def add_bullet(self, count):
      self.bullet_count += count

    def shoot(self):
        # 判断子弹的数量
        if self.bullet_count <= 0:
            print("[%s] 没有子弹了。。。" % self.mode)
            return

        # 发射子弹计算剩余子弹
        self.bullet_count -= 1

        # 提示用户信息
        print("[%s] 发射成功。。。[%d]" % (self.mode, self.bullet_count))


class Soldier:
    def __init__(self, name):
        self.name = name
        self.gun = None

    def fire(self):
        # 判断是否有枪
        if self.gun is None:
            print("[%s] 还没有抢" % self.name)
            return

        # 大喊口号
        print("冲啊...[%s]" % self.name)

        # 装填子弹
        self.gun.add_bullet(50)

        # 射击
        self.gun.shoot()


ak47 = GUN("ak47")
xu = Soldier("许三多")
xu.gun = ak47
xu.fire()
06 身份运算符

身份运算符用于比较两个对象的内存地址是否一致——是否是对同一个对象的引用

  • Python 中针对 None 比较时,建议使用is判断
运算符描述实例
isis是判断两个标识符是不是引用同一个对象x is y,类似id(x)==id(y)
is notis not 是判断两个标识符是不是引用不同对象x is not y,类似id(x)!=id(y)

is==的区别

is 用于判断两个变量引用对象是否为同一个

== 用于判断引用变量的值是否相等

In [1]: a = [1,2,3]

In [2]: a
Out[2]: [1, 2, 3]

In [3]: b = [1,2,3]

In [4]: id (a)
Out[4]: 139793827236464

In [5]: id (b)
Out[5]: 139793811716720

In [6]: a is b
Out[6]: False

In [7]: a == b
Out[7]: True

私有属性和私有方法

01 应用场景及定义方式

应用场景

  • 在实际开发中,对象的某些属性或方法可能只希望在对象的内部被使用,而不希望在外部被访问到
  • 私有属性就是对象不希望公开的属性
  • 私有方法就是对象不希望公开的方法

定义方式

  • 在定义属性或方法时,在属性名或者方法名前增加两个下划线,定义的就是私有属性过方法
class Woman:
    def __init__(self, name):
        self.name = name
        self.__age = 18

    def __secret(self):
        # 在对象内部的方法是可以直接访问对象内部的私有属性的
        print("%s 的年龄是 %d" % (self.name, self.__age))


xiaofang = Woman("小芳")
# 私有属性在外界不能直接被访问
# print(xiaofang.__age)
# 私有方法同样不能在外界直接访问
# xiaofang.__secret()

02 伪私有属性和方法

提示:在日常开发中,不要使用这种方式,访问对象的私有属性或私有方法

python 中,并没有正真意义的私有

  • 在给属性,方法命名时,实际是对名称做了一些特殊处理,使得外界无法访问到
  • 处理方式:在名称前面加上__类名 = _类名__名称
# 伪私有属性在外界不能直接被访问,可以这样访问
print(xiaofang._Woman__age)
# 伪私有方法不能在外界直接访问,可以这样访问
xiaofang._Woman__secret()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值