一、运行面向对象思想实现
超级简单需求:老张开车去东北
目的:体会面向对象思想
"""
面向对象设计思想(旧)
需求:老张开车去东北
变化:增加飞机、汽车。。。。
封装:划分类 人类 车类
之前的设计思想图
人类 汽车类
飞机类
。。。
"""
# 以下代码缺点,增加飞机类,还要修改原有代码,违背了设计思想原则里的 开-闭原则(增加新功能,不改变之前的代码)
class Person:
def __init__(self, name=""):
self.name = name
def go_to(self, position, vehicle):
print(self.name, "去", position)
if type(vehicle) == Car:
vehicle.run()
# 新增其他功能,加判断,改动了之前的代码,违背了开闭原则
elif type(vehicle) == Airplane:
vehicle.fly()
class Car:
def run(self):
print('汽车在行驶')
# 新增飞机类
class Airplane:
def fly(self):
print('飞机在飞行')
lw = Person("老张")
c01 = Car()
a01 = Airplane()
lw.go_to("东北", c01)
二:针对以上需求,为了符合开闭原则,引出继承、多态
"""
面向对象设计思想(新)
需求:老张开车去东北
变化:增加飞机。。。。
封装:划分类 人类 车类
继承:隔离 人类 与 具体的交通工具
重写:具体的交通工具 重写 交通工具的方法(彰显子类个性)
现在的设计思想图(抽象---统一---隔离)
1 人类 2 交通工具类(运输) 3 汽车类(运输)
(先用) (后做) 4 飞机类(运输)
。。。
"""
class Person:
def __init__(self, name=""):
self.name = name
def go_to(self, position, vehicle):
print(self.name, "去", position)
vehicle.transpost()
class Vehicle:
"""虽然没有具体功能代码,但是隔离 人类 与 具体交通工具(价值)"""
def transpost(self):
pass
# 继承父类,重写父类中的方法(在每行首部位置,快捷键 ctrl+o)
class Car(Vehicle):
def transpost(self):
print('汽车在行驶')
# 新增飞机类
class Airplane(Vehicle):
def transpost(self):
print('飞机在飞行')
lw = Person("老张")
c01 = Car()
a01 = Airplane()
lw.go_to("东北", c01)
三、练习体会面向对象开闭原则
"""
设计思想框架练习:
情景:手雷爆炸,伤害敌人或者玩家生命
变化:还可能影响树、房子、鸭子。。。
要求:增加新事物,不影响手雷
体会:开闭原则
"""
# --------架构师---------
class Grenades:
def explode(self, target):
print("手雷爆炸了")
target.reduce()
class Target:
def reduce(self):
pass
# -------程序员----------
class Enemy(Target):
def reduce(self):
print("敌人死了")
class Player(Target):
def reduce(self):
print("玩家受伤了")
class Tree(Target):
def reduce(self):
print("树木落叶了")
g01 = Grenades()
e01 = Enemy()
g01.explode(e01)
四、多态(练习题体会面向对象的三大特征和六大原则)
"""
多态
概念:父类的同一种动作或行为,在不同的子类上有不同的体现
步骤:
1>父类的同一种动作或行为(调用父)
2>子重写
3>创建子
目的:
在继承的基础上,体现类型的个性(彰显子类个性)
增强程序扩展性,体现开闭原则
"""
"""
设计原则
1、开闭原则
2、类的单一职责
概念:一个类有且只有一个改变他的原因
3、依赖倒置(依赖抽象) 引出继承
4、组合复用原则
如果仅仅为了代码复用优先选择组合复用(是一个),非继承复用(是一种)
5、里氏替换
1>父类出现的地方被子类替换,替换后依然保留父类功能
2>子类在重写父类的方法时,尽量选择扩展重写
6、迪米特法则:低耦合
"""
"""
创建图形管理器(该习题综合面向对象三大特征以及六大原则整合的题,非常有价值)
1、记录多个图形(圆形、矩形。。。)
2、求这个图形的总面积
三大特征
封装:创建图形管理器类、圆形面积类、矩形面积类
继承:创建图形类(抽象/统一/隔离)
多态:图形管理器 调用 图形
圆形、矩形重写图形
向图形管理器添加圆形、矩形对象
六大原则
开闭:增加新图形,图形管理器不变
单一职责:
图形管理器管理所有图形
圆形 计算圆形面积
矩形 计算矩形面积
依赖倒置:图形管理器 使用父 图形
组合复用:图形管理器 与 图形
"""
class GraphManager:
def __init__(self):
self.all_graphic = []
# graphic 父类
def add_graphic(self, graphic):
self.all_graphic.append(graphic)
# 计算总面积
def calculate_total_area(self):
total_area = 0
for graphic in self.all_graphic:
# 使用所有图形统一的计算面积行为
total_area += graphic.get_area()
return total_area
class Graphic:
def get_area(self):
# 计算该图形面积
# return 图形面积
pass
# 父类在约束所有子类在某一行为上过达到统一
class Circle(Graphic):
def __init__(self, r):
self.r = r
def get_area(self):
return 3.14 * self.r ** 2
class Rectanle(Graphic):
def __init__(self, l, w):
self.l = l
self.w = w
def get_area(self):
return 3.14 * self.l * self.w
manager = GraphManager()
manager.add_graphic(Circle(5))
manager.add_graphic(Rectanle(5, 6))
print(manager.calculate_total_area())
五、针对上述代码进行的优化代码如下
class EmployeeManager:
# 创建一个员工管理器类,为了不被其他人操作里边的数据,所以做成了私有化(__)
def __init__(self):
self.__all_employee = []
# 创建添加员工方法
def add_employee(self, employee):
# 为了检测传进来的值是否属于员工,所以需要加个判断,只有当传入的对象是一种员工,才能加入到员工管理器
if isinstance(employee, Employee):
self.__all_employee.append(employee)
# 创建计算员工总薪资方法
def calculate_total_money(self):
total_money = 0
for employee in self.__all_employee:
total_money += employee.get_money()
return total_money
# 为了体现继承,创建员工父类,隔离员工管理器类直接调用具体员工岗位类
class Employee:
def __init__(self, base_salary):
self.base_salary = base_salary
def get_money(self):
pass
class Programmer(Employee):
def __init__(self, base_salary, bonus):
super().__init__(base_salary)
self.bonus = bonus
def get_money(self):
# 先通过父类的方法获取底薪
base_salary = super().get_money()
return base_salary + self.bonus
class Tester(Employee):
def __init__(self, base_salary, bugs):
super().__init__(base_salary)
self.bugs = bugs
def get_money(self):
return super().get_money() + self.bugs * 5
employee = EmployeeManager()
employee.add_employee(Programmer(8000, 10000))
employee.add_employee(Tester(5000, 500))
# 该对象传入的是非员工类,在添加到员工管理器的时候加判断了。
# employee.add_employee("大爷")
print(employee.calculate_total_money())