面向对象特性
三大特性:封装、继承、多态(三大基石)
封装
1. 任何对象都有一个明确的边界,把属性、方法保护在边界之内,称为封装。
2. 封装的粒度:
1. 粒度过大:对象过于复杂,过程过于简单
2. 粒度过小:对象过于简单,让过程过于复杂
封装的粒度要控制在一个范围内(主观控制)
继承
类
大熊猫--->熊--->动物类--->生物类
满足? is a的关系---有父子的关系
父类:更加抽象(范围更广)
子类:更加的特殊,基于父类,有自己特殊的地方
交通运输工具:汽车、飞机、轮船、自行车、火车
汽车是一种交通工具 交通工具是一种汽车
语法:
class 子类类名(父类类名):
父类:基类、超类 Baseclass
object:是所有类的父类---根类
class Animals(object):
def __init__(self):
self.leg = 4
def eat(self):
print('我要喝牛奶')
class Panda(Animals):
def eat(self):
print('我要吃竹子')
panda = Panda()
print(panda.leg)
panda.eat()
- 继承的特点
1. 子类可以继承父类的成员
属性、方法
2. 子类不能继承父类中的私有成员
3. 具有扩展性
1. 子类可以有自己的属性和方法
2. 父类扩展了子类
4. 父类可以有多个子类,子类也可以继承多个父类
python中的继承是多继承
5. 如果子类有构造方法,则调用子类的构造方法,如果子类没有构造方法,则调用父类的构造方法
6. 如果一个类没有书写任何的继承关系,那么会默认继承object类
object方法中有构造方法
7. 子类可以调用父类中的成员
1. 父类名.成员名()
class Animals:
def __init__(self):
self.leg = 4
def eat(self):
print('我要喝牛奶')
class Cat():
def __init__(self):
self.leg = 5
def eye(self):
print('两个眼睛')
class Panda(Animals,Cat):
def eat(self):
print('我要吃竹子')
print(Animals.eat(self))
print(self.leg)
panda = Panda()
panda.eat()
- 多继承
1. 钻石继承问题(菱形继承问题)
子类可以继承多个父类,且多个父类继承了同一个父类
导致:
越高级的父类,会被创建的次数,越多。大量的浪费空间。
2. 解决方案:
mro:继承链
根据mro继承链,只继承右边的父类
super()的用法:通过链式关系,调用本类右边的类
- 补充
1. 继承
1. 子类可以继承父类
2. 子类能继承爷爷类
3. 同类不能相互继承
4. 父类不能继承子类
- 方法覆盖
1. 子类可以定义和父类同名的方法,此时则发生了方法覆盖,子类用特有的方法覆盖了父类中共性的方法、2. 也称之为方法重写3. 子类使用特殊的方法实现替换了父类抽象方法的实现4. 父类中的方法,如果被覆盖,则不执行父类中方法的实现,但是父类中的方法还有用:接口 接口:标准注意:父类的方法,都别改,动都别动,只能覆盖
多态
- 多态
1. 一类事物具有多种形态 例如: 人类:男性、女性 序列:list、str、tuple、range 动物:猫、狗、鸡、鸭、鹅2. 多态和继承息息相关(没有继承就没有多态)
# @Time : 2021/8/25 14:04 # @Author : XX# @File : 多态.py # @Software: PyCharmclass Animal: def eat(self): print('动物会吃饭') def sleep(self): print('动物会睡觉') def move(self): print('动物会动')class Dog(Animal): def eat(self): print('狗吃狗粮')class Panda(Animal): def eat(self): print('熊猫吃竹子')class Tiger(Animal): def eat(self): print('老虎吃鸡')d = Dog()p = Panda()t = Tiger()d.eat()p.eat()t.eat()
- 多态性
1. 向不同的对象发送同一条信息,不同的对象可以产生不同的行为多态和多态性不是一个东西,但是相辅相成
# @Time : 2021/8/25 14:11 # @Author : XX# @File : 多态性.py # @Software: PyCharmclass Bird: def fly(self): print('鸟会飞')class Human: def fly(self): print('人会摔死')class Cow: def fly(self): print('牛会被吹飞')def play(obj): obj.fly()b = Bird()h = Human()c = Cow()play(b)play(h)play(c)
- 多态和多态性的关系
1. 多态增加程序的扩展性2. 多态性增加了程序使用的灵活性 以不变,应万变
装饰器
1. 是一种著名的设计模式:(23种) 装饰器模式2. 应用于有切面需求的场景 切面:在不改源码的情况下,切入其他代码(功能) 添加日志 性能测试3. 可以抽离出大量的功能,该功能不影响正常操作 将大量的功能切入到程序中,不影响正常功能。---人为控制
- 装饰器
1. Decorator 装饰器 关键字:@2. 装饰器必须出现在被装饰对象的前一行 被装饰对象:函数对象、类对象3. 装饰器本身也是一个对象4. 语法形式: @funcA def funcB(): pass 以上这种方式,描述的是: funcB() = funcA(funcB) 被装饰的对象,在调用时会被修改成:将被装饰的对象作为参数传递给装饰器,再次对装饰器执行完毕的返回值进行二次调用。
- 补充
python的内置装饰器@staticmethod---静态方法---该方法不和self绑定@classmethod---类方法:自动传入当前类的对象@ property---
- 练习
1. 定义一个函数,测试打印10W次hello world2. 定义一个装饰器,测试函数执行了多长时间3. 提示: import time模块---时间相关的模块 time.time()可以获取当前时间 用时:结束时间-开始时间
刚工作: 不要写纯面向过程的代码---低级代码 也不要直接上设计模式---高级代码
- 魔法师-战士
# @Time : 2021/8/26 9:37 # @Author : XX# @File : 法师.py # @Software: PyCharm# ⽗类:Role,是所有职业的⽗类class Role(): # 属性:name,表示⻆⾊的名字 def __init__(self,name,magic_lv=None,power_lv=None): self.name = name # 法师的魔法等级 self.magic_lv = magic_lv # 战士的属性值 self.power_lv = power_lv # ⽅法:attack(), 返回值为⻆⾊的攻击对敌⼈的伤害 def attack(self): pass# Role有两个⼦类:# 1. 魔法师:Magicerclass Magicer(Role): # 属性:魔法等级:1~10 # 属性从Role类中继承得来 # ⽅法:attack(),该⽅法返回法师对敌⼈造成的伤害 def attack(self): # 伤害:魔法等级*5 return self.magic_lv * 5# 2. 战⼠:Soldierclass Soldier(Role): # 属性:攻击伤害值 # 属性继承于Role类 # ⽅法:attack(),该⽅法返回战⼠的攻击对敌⼈造成的伤害值 # 战⼠的攻击伤害为:攻击伤害属性值 def attack(self): return self.power_lv# 3. 再设计⼀个Team类,表示⼀个组队,具有如下class Team: def __init__(self): self.team = [] # ⽅法: # 1. addMember,表示组队增加⼀个成员 # 注意:组队成员最多6⼈ def addMember(self,member): if len(self.team) < 6: self.team.append(member) else: print('您的队伍已满') # 2. attackSum,表示组队所有成员进⾏攻击时,对敌⼈造成的总伤害 def attackSum(self): sums = 0 for member in self.team: print(member) sums += member.attack() return sumsqingxin = Magicer(name='qingxin',magic_lv=10)yeluo = Soldier(name='yeluo',power_lv=20)team = Team()team.addMember(qingxin)team.addMember(yeluo)print(team.attackSum())
- property
1. 作用:将属性进行关联,同生共死的 x = property(fget=None,fset=None,fdel=None,doc=None) 把x和被关联属性进行关联2. property也是一个类 x = property(fget=None,fset=None,fdel=None,doc=None) fget:传入被关联属性的get方法 fset:传入被关联属性的set方法 fdel:传入被关联属性的del方法 doc:传入被关联属性的文档说明
# @Time : 2021/8/26 10:45 # @Author : XX# @File : property装饰器.py# @Software: PyCharmclass Student: def __init__(self): self.age = 18 def getAge(self): return self.age def setAge(self,value): self.age = value def delAge(self): del self.age # 通过property将x和age属性进行了关联 x = property(getAge,setAge,delAge)s = Student()# print(s.x)# s.x = 20del s.xprint(s.getAge())
图书管理系统V3 Alpha
每行代码用的都必须是类里面的方法除了流程控制代码和输入代码需求和之前的一样今天下午、明天周日:复习前面所有的内容,周一考试考试:让你自己知道,自己哪儿学的有问题