面向对象封装案例
封装
- 封装是面向对象编程的一大特点
- 面向对象编程的第一步 -- 将属性和方法 封装到一个抽象的类中
=> 一开始就应该先做需求分析,分析这个类有哪些属性和方法 - 外界使用类创建对象,然后让对象调用方法
- 对象方法的细节都被封装在类的内部
=> 封装就是把方法,属性都封装在类中,需要的时候使用类的对象直接进行调用即可
小明爱跑步
需求
- 小明 体重75.0公斤
- 小明每次跑步会减肥0.5公斤
- 小明每次吃东西体重会增加1公斤
class Person:
# Python的属性是在__init__中定义的
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
xiaoming = Person("小明",75.0)
print(xiaoming)
xiaoming.eat()
print(xiaoming)
xiaoming.run()
print(xiaoming)
摆放家具
需求
- 房子(House)有户型,总面积和家具名称列表
- 新房子没有任何的家具
- 家具(HouseItem)有名字和占地面积,其中
bed占地4平米
chest占地2平米
table占地1.5平米 - 将以上三件家具 添加到房子中
- 打印房子时,要求输出:户型,总面积,剩余面积,家具名称列表
剩余面积
- 在创建房子对象时,定于一个剩余面积的属性,初始值和总面积相等
- 在调用
add_item()
向房间添加家具时,让剩余面积 -= 家具面积
思考: 应该先开发哪一个类?
答案: 家具类
- 家具类简单
- 房子要使用到家具,被使用的类,通常应该先被开发
创建家具类
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)
创建房间类
class House:
def __init__(self, house_type, area):
"""
:param house_type: 户型
:param 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)
...
# 2. 创建房子对象
my_home = House("两室一厅", 60)
my_home.add_item(bed)
my_home.add_item(chest)
my_home.add_item(table)
print(my_home)
添加家具
需求
- 判断 家具的面积是否超过剩余面积,如果超过,提示不能添加这件家具
- 将家具的名称追加到家具名称列表中
- 用剩余面积 - 家具面积
def add_item(self, item):
"""
添加家具的方法
:param item: HouseItem的对象
:return: None
"""
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
小结
- 主程序负责创建House和HouseItem的对象
- 让房子对象调用
add_item()
,传入家具的对象 - 面积计算,剩余面积,家具列表等处理都被封装到房子类的内部
一个对象的属性可以是另外一个类创建的对象
士兵突击
需求
- 士兵 许三多有一把AK47
=> 名词提出两个类, 士兵类,枪类 - 士兵可以开火
- 枪 能够 发射 子弹
- 枪 装填 装填子弹 —— 增加子弹数量
开发枪类
class Gun:
def __init__(self, model):
# 1. 枪的型号
self.mode = model
# 2. 子弹数量
self.bullet_count = 0
def add_bullet(self, count):
self.bullet_count += count
def shoot(self):
# 判断是否还有子弹
if self.bullet_count < 1:
print("没有子弹了")
return
# 发射一颗子弹
self.bullet_count -= 1
print("[%s] 发射子弹,突突突... [%s] " % (self.mode, self.bullet_count))
开发士兵类
假设:每个新兵都没有枪
定义没有初始值的属性
在定义属性时,如果不知道设置什么初始值,可以设置为None
=> None
对应Java的null
None
关键字表示什么都没有- 表示一个空对象,没有方法和属性,是一个特殊的常量
- 可以将
None
赋值给任何一个变量
class Soilder:
def __init__(self, name, gun=None):
# 姓名
self.name = name
# 枪,士兵初始是默认没有枪的
# None关键字表示什么都没有
self.gun = gun
def fire(self):
if self.gun == None:
print("[%s] 还没有枪.." % self.name)
return
print("冲啊! [%s]" % self.name)
# 让枪装填子弹
self.gun.add_bullet(50)
# 让枪发射子弹
self.gun.shoot()
# 1.创建枪对象
ak47 = Gun("AK47")
# ak47.add_bullet(50)
# ak47.shoot()
# 2.创建许三多
# 枪的形参传进去是 枪类 的对象
xusanduo = Soilder("许三多", gun=ak47)
xusanduo.fire()
身份运算符
身份运算符用于比较两个对象的内存地址是否一致--是否对同一个对象的引用
=> Python中的is
就类似Java中的equal()
只不过is
是运算符,equal()
是方法
- 在
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
用于判断两个变量 引用对象是否为一个==
用于判断引用变量的值是否相等
=> is是判断内存地址的,==是判断内存地址的值
# a,b内容相同,地址不同
In [1]: a = [1,2,3]
In [2]: b = [1,2,3]
In [3]: a is b
Out[3]: False
In [4]: a = b
In [5]: a is b
Out[5]: True
原文地址:https://www.cnblogs.com/Rowry/p/11869693.html
时间: 2024-11-08 02:33:16