ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python学习笔记14.面向对象封装案例

2021-01-07 18:30:56  阅读:275  来源: 互联网

标签:__ 14 item python self area 面向对象 家具 name


1. 封装

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

2. 案例演练

2.1 案例1:小明爱跑步

需求

  1. 小明体重75.0公斤
  2. 小明每次跑步会减肥0.5公斤
  3. 小明每次吃东西体重增加1公斤
    在这里插入图片描述
    提示:在对象的方法内部,是可以直接访问对象的属性的。

代码实现

class Person:
    def __init__(self,name,weight):
        # self.属性 = 形参
        self.name = name
        self.weight = weight
    def __str__(self):
        print("我的名字叫 %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)

output:
小明 爱跑步,跑步锻炼身体
小明 是吃货,吃完这顿再减肥
我的名字叫 小明 体重是 75.50 公斤

2.2 案例1扩展:小美也爱跑步

需求

  1. 小明和小美都爱跑步
  2. 小明体重75.0公斤
  3. 小美体重45.0公斤
  4. 每次跑步会减肥0.5公斤
  5. 每次吃东西体重增加1公斤
    在这里插入图片描述

提示:

  1. 在对象的方法内部,是可以直接访问对象的属性的
  2. 同一个类创建的多个对象之间,属性互不干扰
# 接上代码
xiaomei = Person("小美", 45.0)
xiaomei.eat()
xiaomei.run()
print(xiaomei)
print(xiaoming)

output:
小美 是吃货,吃完这顿再减肥
小美 爱跑步,跑步锻炼身体
我的名字叫 小美 体重是 45.50 公斤
我的名字叫 小明 体重是 75.50 公斤

2.3 案例2:摆放家具

需求:

  1. 房子(House)有户型、总面积和家具名称列表
    – 新房子没有任何家具
  2. 家具(HouseItem)有名字和占地面积,期中
    – 席梦思(bed)占地4平米
    – 衣柜(chest)占地2平米
    – 餐桌(table)占地1.5平米
  3. 将以上三件家具添加到房子中
  4. 打印房子时,要求输出:户型、总面积、剩余面积、家具名称列表
    在这里插入图片描述

剩余面积

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

Step 1: 创建HouseItem类,并创建家具对象

class HouseItem:
    def __init__(self,name,area):
        self.name = name
        self.area = area
    def __str__(self):
        return "[%s] 占地 %.2f 平米" % (self.name,self.area)
# 1.创建家具对象
bed = HouseItem("席梦思",40)
chest = HouseItem("衣柜",25)
table = HouseItem("餐桌",1.5)

Step 2: 创建House类,并创建房子对象

class House:
    # 因为初始状态下,剩余面积free_area等于area,且没有任何家具,所有不需要定义剩余面积和家具列表的形参。
    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总面积: %.02f[剩余: %.02f]\n家具:%s"
                % (self.house_type, self.area,
                   self.free_area,self.item_list))
    def add_item(self, item):
        print("要添加 %s" % item)

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

小结:

  1. 创建了一个房子类,使用到 __init____str__ 两个内置方法
  2. 准备了一个add_item方法准备添加家具
  3. 使用房子类创建了一个房子对象
  4. 让房子对象调用了三次add_item方法,将三件家具以实参传递到add_item内部

Step 3: 添加家具

需求:

  1. 判断家具的面积是否超过剩余面积,如果超过,提示不能添加这件家具
  2. 将家具的名称追加到家具名称列表中
  3. 用房子的剩余面积 - 家具面积
# ... 
# 修改 add_item方法的内容
    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
# ...

output:
要添加 [席梦思] 占地 40.00 平米
要添加 [衣柜] 占地 30.00 平米
衣柜 的面积太大了,无法添加
要添加 [餐桌] 占地 1.50 平米
户型: 两室一厅
总面积: 60.00[剩余: 18.50]
家具:[‘席梦思’, ‘餐桌’]

2.4 案例3:士兵突击

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

需求:

  1. 士兵许三多有一把AK47
  2. 士兵可以开火
  3. 枪能够发射子弹
  4. 枪装填装填子弹 – 增加子弹数量
    在这里插入图片描述

Step1: 创建Gun类

class Gun:
    def __init__(self,model):
        # 1.枪的型号
        self.model = model
        # 2. 子弹的数量
        self.bullet_count = 0 # 初始化为0
    def add_bullet(self,count):
        self.bullet_count += count
    def shoot(self):
        # 1.判断子弹数量
        if self.bullet_count <= 0:
            print("[%s]没有子弹了..." % self.model)
            return
        # 2. 发射子弹, -1
        self.bullet_count -= 1
        # 3. 提示发射信息
        print("[%s]突突突...[%d]"%(self.model, self.bullet_count))

ak47 = Gun("AK47")

Step2: 创建Sodier类

开发士兵类:

  • 假设每一个新兵都没有枪。
  • 定义没有初始值的属性:在定义属性时,如果不知道什么初始值,可以设置为None
    None关键字表示什么都没有,表示一个空对象,没有方法和属性,是一个特殊的常量
    – 可以将None赋值给任何一个变量

fire方法需求:

  1. 判断是否有枪
  2. 喊一声口号
  3. 装填子弹
  4. 射击
# 接上代码
class Sodier:
    def __init__(self,name):
        # 1. 姓名
        self.name = name
        # 2. 枪 -- 新兵没有枪
        self.gun = None
    def fire(self):
        # 1. 判断是否有枪
        if self.gun == None:
            print("%s 没有枪" % self.name)
            return
        # 2. 喊一声口号
        print("冲啊...%s"%self.name)
        # 3. 装填子弹
        self.gun.add_bullet(50)
        # 4. 射击
        self.gun.shoot()

# 创建许三多
xusanduo = Sodier("许三多")
xusanduo.gun = ak47
xusanduo.fire()

output:
冲啊…许三多
[AK47]突突突…[49]

3. 身份运算符

身份运算符用于比较两个对象内存地址是否一直 – 是否是对同一个对象的引用
在python中,针对None比较时,建议使用is判断

运算符描述实例
isis是判断两个标识符是不是引用同一个对象x is y, 类似 id(x) == id(y)
is notis not 是判断两个标识符是不是引用不同对象x is not y, 类似 id(a) != id(b)

is== 区别

  • is 用于判断两个变量引用的对象是否为同一个
  • == 用于判断引用变量的值是否相等

举个栗子

a = [1,2,3]
print(id(a))   # output: 1912404021440
b = [1,2]
print(id(b))   # output: 1912403905664
b.append(3)
print(b)       # output: [1,2,3]
a == b         # output: True
a is b         # output: false

举个栗子
在实现士兵突击案例时,当我们使用self.gun == None时,提示信息显示"PEP 8: E711 comparison to None should be ‘if cond is None:’",这是因为在python中,针对None进行比较时,建议用is判断。
在这里插入图片描述

标签:__,14,item,python,self,area,面向对象,家具,name
来源: https://blog.csdn.net/weixin_42259614/article/details/112307460

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有