面向对象的延续
复习
封装:
封装数据:多 --> 一
封装行为:隐藏 --> 提供必要功能
设计角度:分而治之,变则疏之
继承:
继承行为:子类可以直接使用父类的方法
继承数据:子类在构造函数中通过super()调用父类构造函数
设计角度:抽象 --> 统一 --> 隔离
多态:
语法角度:调用父方法,重写,创建子类对象
设计角度:调用父类一个方法,在不同的子类上有不同的实现.
开闭原则:
可以增加新功能,不修改客户端的代码.
单一职责:
类有且只有一个改变的原因
依赖倒置
调用父类,不调用子类.
组合复用
如果仅仅是代码的复用,优先使用组合关系,而不是继承关系
class A:
def func01(self):
pass
class A1(A):
def func01(self):
print("func02")
class A2(A):
# 重写
def func01(self):
print("func02")
# 动态:运行时可以改变
def func02(a):
# 1. 调用的是父类类(A)
a.func01()
# 3. 创建子类对象
func02(A1())
func02(A2())
"""
多继承
有多种变化需要隔离(不是代码复用)
16:50
"""
class A:
def func01(self):
print("A -- func01")
class B(A):
def func01(self):
print("B -- func01")
class C(A):
def func01(self):
print("C -- func01")
class D(C, B):
def func01(self):
print("D -- func01")
# 1. 如何调用某一个同名方法
B.func01(self)
d = D()
d.func01()
# 2. 同名方法解析顺序
print(D.mro())
"""
里氏替换
"""
class Granade:
def __init__(self, atk=0):
self.atk = atk
def explode(self, target):
print("手雷爆炸啦")
target.damage(self.atk)
class Target:
def __init__(self, hp=0):
self.hp = hp
def damage(self, value):
self.hp -= value
# ------------------------------------------
class Player(Target):
def damage(self, value):
super().damage(value)
print("玩家受伤,屏幕碎屏")
class Enemy(Target):
def damage(self, value):
super().damage(value)
print("敌人受伤,掉下装备")
g01 = Granade()
g01.explode(Player())
g01.explode(Enemy())
"""
运算符重载
"""
class Vector2:
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def __str__(self):
return "向量的x分量为%d,y分量为%d" % (self.x, self.y)
def __add__(self, other):
return Vector2(self.x + other.x, self.y + other.y)
def __iadd__(self, other):
self.x += other.x
self.y += other.y
return self
# 比较相同
def __eq__(self, other):
return self.x == other.x and self.y == other.y
# 比较大小
def __lt__(self, other):
return self.x < other.x
pos = Vector2(10, 25)
dir = Vector2(1, 0)
print(pos + dir) # pos.__add__(dir)
pos += dir
print(pos)
# list01 = [10]
# list01 += [20]# 在原有对象中添加新元素(在原有可变对象上修改)
# print(list01) # [10, 20]
#
# list02 = [10]
# list02 = list02 + [20] # 创建了新对象
# print(list02) # [10, 20]
v01 = Vector2(100, 200)
v02 = Vector2(100, 200)
print(v01 == v02) #
list_vectors = [
Vector2(200, 200),
Vector2(400, 400),
Vector2(100, 100),
Vector2(300, 300),
Vector2(500, 500),
]
print(list_vectors.count(Vector2(100, 100)))
for item in sorted(list_vectors):
print(item)
"""
内置可重写函数
"""
class Wife:
def __init__(self, name, face_score, money):
self.name = name
self.face_score = face_score
self.money = money
# 重写__str__作用是:定义当前对象转换的字符串格式
# 显示对象时使用(没有格式限制)
def __str__(self):
return "臣妾%s,颜值%d,存款%f." % (self.name, self.face_score, self.money)
# 重写__repr__作用是:定义当前对象转换的字符串格式
# 克隆当前对象(python语法格式)
def __repr__(self):
return 'Wife("%s", %d, %f)' % (self.name, self.face_score, self.money)
w01 = Wife("双儿", 100, 50000)
message = w01.__str__()
print(message) # <__main__.Wife object at 0x7ff8a3224cf8>
w02 = Wife("阿珂", 150, 20000)
print(w02)
str_code = w01.__repr__()
# eval:将字符串作为python代码执行
w03 = eval(str_code) # 克隆老婆对象
w01.name = "双双"
print(w03.name) #
面向对象逻辑:
"""
一家公司有如下几种岗位:
程序员:底薪 + 项目分红
测试员:底薪 + Bug * 5
....
创建员工管理器
记录所有员工
提供计算总工资的功能
叙述:
三大特征:
封装:根据需求划分为员工管理器、程序员、测试员
继承:创建员工类,隔离员工管理器与具体员工的变化
多态:员工管理器调用员工,具体员工重写员工的计算薪资方法,添加具体员工对象
(调父) (重写) (创建子类对象)
总结多态步骤:面对变化点,需要使用3步进行处理。
价值(作用):程序灵活(扩展性强 = 开闭原则)
六大原则:
开闭原则:增加员工种类,员工管理器不变.
单一职责:员工管理器:统一管理所有员工(薪资...)
程序员:定义该员工的薪资算法(底薪 + 项目分红)
测试员:定义该员工的薪资算法(底薪 + Bug * 5)
依赖倒置:员工管理器调用员工,不调用程序员/测试员
组合复用:员工管理器通过组合关系,使用各种员工的薪资算法.
里氏替换:向员工管理器添加的是员工子类对象
员工子类先调用员工类计算薪资方法返回底薪,再添加自己的薪资逻辑.
迪米特:每个具体员工类之间低耦合
员工管理器与具体员工之间低耦合
"""
class EmployeeManager:
def __init__(self):
self.__list_employees = []
def add_employee(self, emp):
self.__list_employees.append(emp)
def get_total_salary(self):
total_salary = 0
for item in self.__list_employees:
# 调用父类
total_salary += item.calculate_salary()
return total_salary
class Employee:
def __init__(self, base_salary=0):
self.base_salary = base_salary
def calculate_salary(self):
return self.base_salary
# --------------------------
class Programmer(Employee):
def __init__(self, base_salary=0, bonus=0):
super().__init__(base_salary)
self.bonus = bonus
# 重写
def calculate_salary(self):
return super().calculate_salary() + self.bonus
class Tester(Employee):
def __init__(self, base_salary=0, bug_count=0):
super().__init__(base_salary)
self.bug_count = bug_count
def calculate_salary(self):
return super().calculate_salary() + self.bug_count * 5
manager = EmployeeManager()
# 创建子类对象
manager.add_employee(Programmer(8000, 20000))
manager.add_employee(Tester(5000, 100))
print(manager.get_total_salary())
"""
技能系统
叙述
三大特征:
六大原则:
"""
class ImpactEffect:
"""
影响效果,隔离技能释放器与具体效果(眩晕,降低速度...)
"""
def impact(self):
pass
class CostSPEffect(ImpactEffect):
def __init__(self, value=0):
self.value = value
def impact(self):
super().impact()
print("消耗%d法力" % self.value)
class DamageEffect(ImpactEffect):
def __init__(self, value=0):
self.value = value
def impact(self):
super().impact()
print("伤害%d生命" % self.value)
class LowerDeffenseEffect(ImpactEffect):
def __init__(self, value=0, duration=0):
self.value = value
self.duration = duration
def impact(self):
super().impact()
print("降低%f防御力,持续%d秒" % (self.value, self.duration))
class SkillDeployer:
"""
技能释放器
"""
def __init__(self, name=""):
self.name = name
self.__config_file = self.__load_config_file()
self.__list_effects = self.__create_impact_effects()
def __load_config_file(self):
# 模拟配置文件读取后的数据结构
return {
"毁天灭地":["CostSPEffect(200)","DamageEffect(800)"],
"降龙十八掌":["CostSPEffect(150)","DamageEffect(600)","LowerDeffenseEffect(0.5,10)"],
}
def __create_impact_effects(self):
# 技能名称k ---> 效果名称列表v
list_effect_names = self.__config_file[ self.name ]
# 创建子类对象()
# list_effect_objects = []
# for itme in list_effect_names:
# effect_obj = eval(itme)
# list_effect_objects.append(effect_obj)
# return list_effect_objects
return [eval(itme) for itme in list_effect_names]
def deploy_skill(self):
print(self.name,"释放啦")
for item in self.__list_effects:
# 调用父类(影响效果)
item.impact()
xlsbz = SkillDeployer("降龙十八掌")
xlsbz.deploy_skill()
xlsbz.deploy_skill()