1.封装
- 封装是面向对象编程的一大特点
- 面向对象编程的第一步--将属性和方法 封装到一个抽象的类中
- 外界使用类创建对象,然后让对象调用方法
- 对象方法的细节都被封装在类的内部
2.案例
2.1小明爱跑步
需求
- 小明体重75.0公斤
- 小明每次跑步会减肥0.5公斤
- 小明每次吃东西体重增加1公斤
person |
name weight |
__init__(self, name, weight): __str__(self): run(self): eat(self): |
提示:在对象的方法内部,是可以直接访问对象的属性的!
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)
2.2小明爱跑步扩展--小美也爱跑步
需求
- 小明和小美都爱跑步
- 小明体重75.0公斤
- 小美体重45.0公斤
- 每次跑步都会减少0.5公斤
- 每次吃东西都会增加1公斤
person |
name weight |
__init__(self, name, weight): __str__(self): run(self): eat(self): |
提示:
- 在对象的方法内部,是可以直接访问对象的属性的
- 同一个类创建的多个对象之间,属性互不干扰!
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.0)
xiaomei.eat()
xiaomei.run()
print(xiaomei)
print(xiaoming)
2.3摆放家具
需求
- 房子(House)有户型、总面积和家具名称列表
- 新房子没有任何的家具
- 家具(HouseItem)有名字和占地面积,其中
- 席梦思(bed) 占地4平方米
- 衣柜(chest) 占地2平方米
- 餐桌(table) 占地1.5平方米
- 将以上三件家具添加到房子中
- 打印房子时,要求输出:户型、总面积、剩余面积、家具名称列表
HouseItem | House | |
name area | house_type area free_area item_list | |
__init__(self, name, area): __str__(self) | __init__(self, house_type, area): __str__(self): add_item(self, item): |
剩余面积
- 在创建房子对象时,定义一个剩余面积的属性,初始值和总面积相等
- 当调用add_item方法,向房间添加家具时,让剩余面积 -=家具面积
思考:应该先开发哪一个类?
答案--家具类
- 家具简单
- 房子要使用到家具,被使用的类,通常应该先开发
2.3.1家具类
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 ("席梦思", 4)
chest = HouseItem ("衣柜", 2)
table = HouseItem ("餐桌", 1.5)
print(bed)
print(chest)
print(table)
2.3.2房子类
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.创建家具
bed = HouseItem ("席梦思", 4)
chest = HouseItem ("衣柜", 2)
table = HouseItem ("餐桌", 1.5)
print(bed)
print(chest)
print(table)
# 2.创建房子对象
my_home = House("两室一厅", 60)
my_home.add_item(bed)
my_home.add_item(chest)
my_home.add_item(table)
print(my_home)
2.3.2添加家具
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
# 2.将家具的名称添加到列表中
self.item_list.append(item.name)
# 3.计算剩余面积
self.free_area -= item.area
# 1.创建家具
bed = HouseItem ("席梦思", 4)
chest = HouseItem ("衣柜", 2)
table = HouseItem ("餐桌", 1.5)
print(bed)
print(chest)
print(table)
# 2.创建房子对象
my_home = House("两室一厅", 60)
my_home.add_item(bed)
my_home.add_item(chest)
my_home.add_item(table)
print(my_home)
2.4士兵突击
需求
- 士兵许三多有一把AK47
- 士兵可以开火
- 枪能够发射子弹
- 枪装填子弹--增加子弹数量
Soldier | Gun | |
name gun | model bullet__count | |
__init__(self): fire(self): | __init__(self, model): add_bullet(self, count): shoot(self): |
2.4.1枪类
class Gun:
def __init__(self, model):
# 1.枪的型号
self.model = model
# 2.子弹的数量
self.bullet_count = 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 ))
# 1.创建枪对象
ak47 = Gun("AK47")
ak47.add_bullet(50)
ak47.shoot()
2.4.2士兵类
假设:每一个新兵都没有枪
定义没有初始值的属性
在定义属性时,如果不知道设置什么初始值,可以设置为None
- None关键字表示什么都没有
- 表示一个 空对象,没有方法和属性,是一个特殊的常量
- 可以将None赋值给任何一个变量
classclass Gun:
def __init__(self, model):
# 1.枪的型号
self.model = model
# 2.子弹的数量
self.bullet_count = 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 ))
class Solider:
def __init__(self, name):
# 1.姓名
self.name = name
# 2.枪 - 新兵没有枪
self.gun = None
# 1.创建枪对象
ak47 = Gun("AK47")
ak47.add_bullet(50)
ak47.shoot()
# 2.创建许三多
xusanduo = Solider("许三多")
xusanduo.gun = ak47
print(xusanduo.gun)
Gun:
def __init__(self, model):
# 1.枪的型号
self.model = model
# 2.子弹的数量
self.bullet_count = 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 ))
class Solider:
def __init__(self, name):
# 1.姓名
self.name = name
# 2.枪 - 新兵没有枪
self.gun = None
# 1.创建枪对象
ak47 = Gun("AK47")
ak47.add_bullet(50)
ak47.shoot()
# 2.创建许三多
xusanduo = Solider("许三多")
xusanduo.gun = ak47
print(xusanduo.gun)
2.4.3士兵开火
- 判断是否有枪,没有枪没法冲锋
- 喊一声口号
- 装填子弹
- 射击
class Gun:
def __init__(self, model):
# 1.枪的型号
self.model = model
# 2.子弹的数量
self.bullet_count = 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 ))
class Solider:
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()
# 1.创建枪对象
ak47 = Gun("AK47")
# 2.创建许三多
xusanduo = Solider("许三多")
xusanduo.gun = ak47
xusanduo.fire()
print(xusanduo.gun)
3.身份运算符
身份运算符用于比较两个对象的内存地址是否一致--是否是对同一个对象的引用
- 在python中针对None比较时,建议使用is判断
运算符 | 描述 | 实例 |
is | is是判断两个标识符是不是引用同一个对象 | x is y, 类似id(x) == id(y) |
is not | is not | x is not y, 类似id(a) != id(b) |
is 与 == 区别:
is 用于判断两个变量引用对象是否为同一个
==用于判断引用变量的值是否相等
代码见:https://github.com/x45w/python_fengzhuang.git