Python基础之面向对象2(封装)

时间:2021-09-29 13:59:00

一、封装定义:

  Python基础之面向对象2(封装)

 二、作用

  Python基础之面向对象2(封装)

三、私有成员:

  1、基本概念及作用

    Python基础之面向对象2(封装)

  2、__slots__手段私有成员:

    Python基础之面向对象2(封装)

  3、@property属性手段私有成员:

    Python基础之面向对象2(封装)

四、基础示例代码

  1、用方法封装变量

    

"""
练习:用方法封装变量
"""
class Enemy:
def __init__(self,name,atk,speed,hp):
self.set_name(name)
self.set_atk(atk)
self.set_atk_speed(speed)
self.set_hp(hp) def get_name(self):
return self.__name def set_name(self,value):
self.__name = value def get_atk(self):
return self.__atk def set_atk(self, value):
self.__atk = value def get_atk_speed(self):
return self.__atk_speed def set_atk_speed(self, value):
if 0 <= value <= 10:
self.__atk_speed = value
else:
self.__atk_speed = 0
print("速度不再范围内,赋值失败") def get_hp(self):
return self.__hp def set_hp(self, value):
if 0 <= value <= 100:
self.__hp = value
else:
self.__hp = 0
print("血量不再范围内,赋值失败") e01 = Enemy("zs",200,50,200)
print(e01.get_name(),e01.get_hp(),e01.get_atk_speed())

   2、用属性封装变量:

    

"""
练习:属性封装变量
""" class Enemy:
def __init__(self, name, atk, speed, hp):
self.name = name
self.atk = atk
self.speed = speed
self.hp = hp @property
def name(self):
return self.__name @name.setter
def name(self,value):
self.__name = value @property
def atk(self):
return self.__atk @atk.setter
def atk(self, value):
self.__atk = value @property
def speed(self):
return self.__speed @speed.setter
def speed(self, value):
self.__speed = value @property
def hp(self):
return self.__hp @hp.setter
def hp(self, value):
self.__hp= value e01 = Enemy("zs", 200, 50, 200)
print(e01.name, e01.hp, e01.speed)

    3、基础代码1

    

"""
封装数据优势:
1.符合人类思考方式
2.将数据与对数据的操作封装起来。 使用方法封装变量
""" class Wife01:
def __init__(self, name, age):
self.name = name
# 缺点:缺乏对象数据的封装,外界可以随意赋值.
self.age = age w01 = Wife01("芳芳", 26)
w02 = Wife01("铁锤", 86)
w02.age = 87
# print(w02.age) # 注意:通过两个方法,读写私有变量.
# 练习:定义敌人类(姓名,攻击力,攻击速度(0-10),血量(0--100))
class Wife02:
def __init__(self, name = "", age = 0):
self.set_name(name)
# 私有成员:障眼法(解释器会改变双下划线开头的变量名)
# self.__age = age
self.set_age(age) def get_name(self):
return self.__name def set_name(self,value):
self.__name = value def get_age(self):
return self.__age def set_age(self,value):
if 20 <= value <= 30:
self.__age = value
else:
print("我不要") w01 = Wife02("铁锤",86)
# 找不到双下划线开头的数据
# print(w01.__age)
# 通过下划线 + 类名 可以访问双下划线开头的数据
# print(w01._Wife02__age)
w01.set_age(50)
print(w01.get_age())
print(w01.__dict__)

    4、基础代码2:

    

"""
使用属性封装变量
""" # 练习:修改Enemy类,使用属性封装变量
class Wife:
def __init__(self, name="", age=0):
self.name = name # 调用 @name.setter 修饰的方法
self.age = age # 调用 @age.setter 修饰的方法 @property # 拦截读取变量的操作
def name(self): # get_name()
return self.__name @name.setter # 拦截写入变量的操作
def name(self, value): # set_name()
self.__name = value @property
def age(self):
return self.__age @age.setter
def age(self, value):
if 20 <= value <= 30:
self.__age = value
else:
self.__age = 0
print("我不要") w01 = Wife("铁锤", 86)
print(w01.name)
print(w01.age)

  5、基础代码3:

    

"""
__slots__ 属性
"""
class SkillData:
# 限制当前类,创建的对象,只能具有的实例变量.
__slots__ = ("__name") def __init__(self, name):
self.name = name @property
def name(self):
return self.__name @name.setter
def name(self, value):
self.__name = value s01 = SkillData("技能名称")
# s01.name = "降龙十八掌"
print(s01.name)
# 为当前对象,添加实例变量
# s01.time = 5
# print(s01.time)
# print(s01.__dict__) # 因为使用了__slots__属性,所以不是使用__dict__.

   6、基础代码4:

   

"""
需求: 老张开去车东北.
分而治之 -- 分解
变化点
练习:exercise01
""" #需求: 老张开去车东北.
class Person:
def __init__(self, name):
self.name = name def go_to(self, type, str_pos):
type.run(str_pos) class Car:
def run(self, str_pos):
print("行驶到", str_pos) p01 = Person("老张")
c01 = Car()
p01.go_to(c01, "东北")

五、实例练习:

   练习1:

    

"""
以面向对象的思想,描述下列场景.
提示:对象与对象数据不同,类与类行为不同.
  张三 教 李四 学习python
李四 教 张三  玩游戏
张三 工作 挣了8000元
李四 工作 挣了3000元
""" class Person:
def __init__(self, name):
# 人的姓名
self.name = name
# 人会的所有技能
self.__skills = []
self.__total_money = 0 # 只读属性
@property
def skills(self):
# return self.__skills # 返回可变对象地址,意味着类外仍然可以操作可变对象
return self.__skills[:] # 返回新的可变对象地址,意味着类外仍然操作的是新可变对象,不影响原对象.
# 备注:每次通过切片返回新对象,都会另外开辟空间创建新对象,占用过多内存. # 只读属性
@property
def total_money(self):
return self.__total_money @property
def name(self):
return self.__name @name.setter
def name(self,value):
self.__name = value def teach(self, person_other, str_skill):
# person_other 的技能列表,增加str_skill
person_other.__skills.append(str_skill)
print(self.name, "教了", person_other.name, str_skill) def work(self, money):
self.__total_money += money
print(self.name, "工作挣了", money, "元") zs = Person("张三")
ls = Person("李四")
# 张三 教 李四 学习python
zs.teach(ls, "python")
# 李四 教 张三  玩游戏
ls.teach(zs, "游戏") zs.work(8000)
ls.work(4000) #************************
zs = Person("张三")
# zs.skills = [] # 不能改
# 如果skills属性,返回的是__skills,那么仍然可以操作私有列表
# __skills[:],那么操作的是新列表
zs.skills.append("python")
print(zs.skills)

    练习2:

    

"""
创建技能类(技能名称,冷却时间,持续时间,攻击距离......)
要求:使用属性封装变量
创建技能列表(技能对象的列表)
-- 查找名称是"降龙十八掌"的技能对象
-- 查找名称是持续时间大于10秒的的所有技能对象
-- 查找攻击距离最远的技能对象
-- 按照持续时间,对列表升序排列.
""" class SkillData:
def __init__(self, name, cd, time, distance):
self.name = name
self.cd = cd
self.time = time
self.atk_distance = distance @property
def name(self):
return self.__name @name.setter
def name(self, value):
self.__name = value @property
def cd(self):
return self.__cd @cd.setter
def cd(self, value):
self.__cd = value @property
def time(self):
return self.__time @time.setter
def time(self, value):
self.__time = value @property
def atk_distance(self):
return self.__atk_distance @atk_distance.setter
def atk_distance(self, value):
self.__atk_distance = value def print_self(self):
print(self.name, self.cd, self.time, self.atk_distance) list_skills = [
SkillData("降龙十八掌", 60, 10, 5),
SkillData("如来神掌", 50, 5, 15),
SkillData("六脉神剑", 80, 20, 8),
SkillData("一阳指", 20, 50, 15),
SkillData("冷酷追击", 15, 30, 9),
] # -- 查找名称是"降龙十八掌"的技能对象
for item in list_skills:
if item.name == "降龙十八掌":
item.print_self() # -- 查找名称是持续时间大于10秒的的所有技能对象
result = []
for item in list_skills:
if item.time > 10:
result.append(item) # -- 查找攻击距离最远的技能对象
result = list_skills[0]
for i in range(1, len(list_skills)):
# 后面的技能对象
if result.atk_distance < list_skills[i].atk_distance:
result = list_skills[i]
# result.atk_distance = list_skills[i].atk_distance result.print_self() # -- 按照持续时间,对列表升序排列.
for r in range(len(list_skills) - 1):
for c in range(r + 1, len(list_skills)):
if list_skills[r].time > list_skills[c].time:
list_skills[r],list_skills[c] = list_skills[c],list_skills[r] # 请用调试,查看列表的取值.
print(list_skills)

    练习3:

    

# 练习: 小明在招商银行取钱.
class Person:
def __init__(self, name, money=0):
self.name = name
self.money = money class Bank:
def __init__(self, name, money):
self.name = name
self.total_money = money # 考虑:取钱逻辑,应该由银行决定.所以取钱方法,定义在了银行.
def draw_money(self, person, value):
if self.total_money >= value:
self.total_money -= value
person.money += value
print(person.name, "取钱成功")
else:
print("取钱失败") p01 = Person("小明")
b01 = Bank("招商银行", 100000)
b01.draw_money(p01, 10000000)

    练习4

    

"""
学生管理器系统
""" class StudentModel:
"""
学生数据模型类
""" def __init__(self, name="", age=0, score=0, id=0):
"""
创建学生对象
:param id: 编号
:param name: 姓名
:param age: 年龄
:param score: 成绩
"""
self.id = id
self.name = name
self.age = age
self.score = score @property
def id(self):
return self.__id @id.setter
def id(self, value):
self.__id = value @property
def name(self):
return self.__name @name.setter
def name(self, value):
self.__name = value @property
def age(self):
return self.__age @age.setter
def age(self, value):
self.__age = value @property
def score(self):
return self.__score @score.setter
def score(self, value):
self.__score = value class StudentManagerController:
"""
学生逻辑控制器
""" def __init__(self):
self.__list_stu = [] @property
def list_stu(self):
return self.__list_stu def add_student(self, stu):
"""
添加新学生
:param stu: 需要添加的学生对象
"""
stu.id = self.__generate_id()
self.__list_stu.append(stu) def __generate_id(self):
# 生成编号的需求:新编号,比上次添加的对象编号多1.
# if len(self.__list_stu) > 0:
# id = self.__list_stu[-1].id + 1
# else:
# id = 1
# return id
return self.__list_stu[-1].id + 1 if len(self.__list_stu) > 0 else 1 # controller = StudentManagerController()
# controller.add_student(StudentModel("zs",18,85))
# controller.add_student(StudentModel("zs",18,85))
# for item in controller.list_stu:
# print(item.id,item.name,item.age,item.score) class StudentManagerView:
"""
界面视图类
"""
def __init__(self):
# 创建逻辑控制器对象
self.__manager = StudentManagerController() def __input_students(self):
# 1. 在控制台中录入学生信息,存成学生对象StudentModel.
stu = StudentModel()
stu.name = input("请输入姓名:")
stu.age = int(input("请输入年龄:"))
stu.score = int(input("请输入成绩:"))
# 2. 调用逻辑控制器的add_student方法
self.__manager.add_student(stu)
print(self.__manager) def __display_menu(self):
"""
显示菜单
:return:
"""
print("1) 添加学生")
print("2) 显示学生")
print("3) 删除学生")
print("4) 修改学生")
print("5) 按照成绩降序排列") def __select_menu(self):
"""
选择菜单
:return:
"""
number = input("请输入选项:")
if number == "":
self.__input_students()
elif number == "":
pass
elif number == "":
pass
elif number == "":
pass
elif number == "":
pass def main(self):
"""
界面入口方法
:return:
"""
while True:
self.__display_menu()
self.__select_menu() view = StudentManagerView()
view.main()

    内存图如下:

    Python基础之面向对象2(封装)

  练习5

    

# 1. 使用面向对象思想,写出下列场景:
# 玩家(攻击力)攻击敌人,敌人受伤(血量)后掉血,还可能死亡(播放动画).
# 敌人(攻击力)攻击力攻击玩家,玩家(血量)受伤后碎屏,还可能死亡(游戏结束).
# 程序调试,画出内存图. class Player:
"""
玩家类
"""
def __init__(self,hp,atk):
self.atk = atk
self.hp = hp def attack(self,enemy):
print("打死你")
# 调用敌人受伤方法(敌人负责定义受伤逻辑)
enemy.damage(self.atk) def damage(self,value):
self.hp -= value
print("玩家受伤啦,屏幕碎啦")
if self.hp <= 0:
self.__death() def __death(self):
print("玩家死亡,游戏结束") class Enemy:
def __init__(self,hp,atk):
self.hp = hp
self.atk = atk def damage(self,value):
self.hp -= value
print("受伤啦")
if self.hp <= 0:
self.__death() def attack(self,player):
print("打死你")
player.damage(self.atk) def __death(self):
print("死啦,播放动画") p01 = Player(100,50)
e01 = Enemy(60,10)
# 玩家打敌人
p01.attack(e01)
# p01.attack(e01)
e01.attack(p01)

    内存图如下:

    Python基础之面向对象2(封装)

    

Python基础之面向对象2(封装)的更多相关文章

  1. python基础&comma;函数&comma;面向对象&comma;模块练习

    ---恢复内容开始--- python基础,函数,面向对象,模块练习 1,简述python中基本数据类型中表示False的数据有哪些? #  [] {} () None 0 2,位和字节的关系? # ...

  2. (转)Python成长之路【第九篇】:Python基础之面向对象

    一.三大编程范式 正本清源一:有人说,函数式编程就是用函数编程-->错误1 编程范式即编程的方法论,标识一种编程风格 大家学习了基本的Python语法后,大家就可以写Python代码了,然后每个 ...

  3. Python 基础 四 面向对象杂谈

    Python 基础  四  面向对象杂谈 一.isinstance(obj,cls) 与issubcalss(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls ...

  4. 自学Python之路-Python基础&plus;模块&plus;面向对象&plus;函数

    自学Python之路-Python基础+模块+面向对象+函数 自学Python之路[第一回]:初识Python    1.1 自学Python1.1-简介    1.2 自学Python1.2-环境的 ...

  5. 二十&period; Python基础&lpar;20&rpar;--面向对象的基础

    二十. Python基础(20)--面向对象的基础 1 ● 类/对象/实例化 类:具有相同属性.和方法的一类人/事/物 对象(实例): 具体的某一个人/事/物 实例化: 用类创建对象的过程→类名(参数 ...

  6. python基础&lpar;25&rpar;&colon;面向对象三大特性二&lpar;多态、封装&rpar;

    1. 多态 1.1 什么是多态 多态指的是一类事物有多种形态. 动物有多种形态:人,狗,猪. import abc class Animal(metaclass=abc.ABCMeta): #同一类事 ...

  7. python之路----面向对象的封装特性

    封装 [封装] 隐藏对象的属性和实现细节,仅对外提供公共访问方式. 广义上面向对象的封装 :代码的保护,面向对象的思想本身就是一种只让自己的对象能调用自己类中的方法 狭义上的封装 —— 面向对象的三大 ...

  8. Python高手之路【十一】python基础之面向对象

    创建类和对象 面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用. 类就是一个模板,模板里可以包含多个函数, ...

  9. 学习PYTHON之路, DAY 7 - PYTHON 基础 7 &lpar;面向对象基础&rpar;

    面向对象三大特性 一.封装 封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容. 所以,在使用面向对象的封装特性时,需要: 将内容封装到某处 从某处调用被封装的内容 第一步:将内容 ...

  10. Day7 - Python基础7 面向对象编程进阶

    Python之路,Day7 - 面向对象编程进阶   本节内容: 面向对象高级语法部分 经典类vs新式类 静态方法.类方法.属性方法 类的特殊方法 反射 异常处理 Socket开发基础 作业:开发一个 ...

随机推荐

  1. session超时时间设置方法

    session超时时间设置方法 由于session值之前没有设置,以至于刚登录的网站,不到一分钟就超时了,总结了一下,原来是session过期的原因,以下是设置session时间的3个方法: 1. 在 ...

  2. css样式控制 字符个数,多余的字用省略号代替

    大家好,我是小菜 前端 ,技术不高,正在努力中充电!希望大家多多指教 <div class="show">大家好,我是小菜 前端 ,技术不高,正在努力中充电!希望大家多 ...

  3. php 反射

    一.通过{属性名} 对对象赋值.        $book=new Book();        $propertyName="name";        $propertyVal ...

  4. ubuntu下安装程序的三种方法

    引言 在ubuntu当中,安装应用程序我所知道的有三种方法,分别是apt-get,dpkg安装deb和make install安装源码包三种.下面针对每一种方法各举例来说明. apt-get方法 使用 ...

  5. XCOJ 1102 &lpar;树形DP&plus;背包&rpar;

    题目链接: http://xcacm.hfut.edu.cn/oj/problem.php?id=1102 题目大意:树上取点.父亲出现了,其儿子包括孙子...都不能出现.给定预算,问最大值. 解题思 ...

  6. JSON的转换(将JSON转换为字符串,将字符串转化为JSON)

    eval()和JSON.stringify()   1.eval用于从一个字符串中解析出json 对象,创建包含 JSON 语法的 JavaScript 字符串.例如 var str = '{ &qu ...

  7. Android调用第三方so

    http://blog.csdn.net/jiuyueguang/article/details/9450597 ubuntu下整合eclipse和javah生成jni头文件开发android的nat ...

  8. Stanford CoreNLP使用需要注意的一点

    1.Stanford CoreNLP maven依赖,jdk依赖1.8 <dependency> <groupId>edu.stanford.nlp</groupId&g ...

  9. Cocos2d-x Touch事件处理机制

    在Cocos2d-x中提供两种触摸事件处理机制:CCStandardTouchDelegate和CCTargetedTouchDelegate. 一.如何使用 0.默认情况下CCLayer都是没有启动 ...

  10. Java命令学习系列(二)——Jstack

    Java命令学习系列(二)——Jstack 2015-04-18 分类:Java 阅读(512) 评论(0) jstack是java虚拟机自带的一种堆栈跟踪工具. 功能 jstack用于生成java虚 ...