面向对象的继承与多态
1.继承
继承 : 一个类除了自身拥有的属性方法外,还获取了另一个类的属性方法
被继承的是父类(基类,超类)
继承的是子类(衍生类)
继承种类:
1.单继承
2.多继承
python中所有类的父类是 object
1.1 单继承
# 单继承
"""
子类只能继承父类的公有成员,不能继承私有成员
在继承的环境中,对象的调取顺序:
对象中->自己类中->父类中 都没有报错
"""
class Human():
person="远古人类"
__mimi="未解之谜"
def drink(self):
print("茹毛饮血")
def __eat(self):
print("吃的是烤肉")
class Man(Human):#继承父类
def siyou(self):
self.__eat()
def drink(self):
print("现代人喝饮料")
obj = Man()
# 1.子类可以使用父类的公有成员
print(obj.person) #远古人类
# 2.子类不能使用父类的私有成员
"""
obj.siyou() #报错 : 'Man' object has no attribute '_Man__eat'
"""
# 3.子类可以重写父类的公有成员
obj.drink() #现代人喝饮料
1.2 多继承
"""
多继承的弊端 :
会造成菱形继承这种情况,理不清调用顺序
super()对象会按照 mro 列表的顺序依次调用,解决菱形继承存在的问题
类名.mro() 返回列表
1.super 本身是一个类,super()是一个对象,用于掉用父类的绑定方法
2.super 只应用在绑定方法中,默认自动传递self参数(前提: super所在作用域存在self)
3.super作用 : 用于解决复杂的多继承调用顺序
经典类: 深度优先(python2.x)
新式类: 广度优先(python3.x)->横着遍历一级父类,二级父类...到最后父类
写多继承时,尽量避免造成不同类相同方法名的情况,提高代码质量 ,高内聚,低耦合
高内聚: 一个模块只完成一个任务,专一性高
低耦合: 模块与模块之间可以彼此独立不冲突,方便移植复用
"""
# 1.多继承
class Father():
pty="抠脚大叔"
def hobby(self):
print("打球")
class Mother():
pty="貌美如花"
def hobby(self):
print("刷韩剧")
class Son(Father,Mother): #继承父类
pty="三好学生"
def hobby(self):
print("LOL")
# 1.使用类调用类中成员
def lei(self):
print(Mother.pty)
Father.hobby(self) #注意参数别忘写
# 2.使用对象调用类中成员
"""对象调用顺序 : 对象成员->自己类成员->父类成员"""
def duixiang(self):
print(self.pty)
self.hobby()
# 3.使用super调用父类中成员
"""绑定方法 : 会自动把作用域self对象当成参数进行传递"""
def sup(self):
print(super().pty) #多个父类成员一样,找第一个继承的父类
super().hobby()
obj = Son()
obj.lei() #貌美如花,打球
obj.duixiang() #三好学生 LOL
obj.sup() #抠脚大叔,打球
# 2.菱形继承(钻石继承)
class Human():
pty=4
def feel(self):
print("天热,脱1")
print(self.pty)
print("天冷,穿虎皮2")
class Man(Human):
pty=3
def feel(self):
print("天热了,光膀子3")
super().feel()
print("天冷了,穿羽绒服4")
class Woman(Human):
pty=2
def feel(self):
print("天热了,脱衣服5")
super().feel()
print("天冷了,穿羽绒服6")
class Son(Man,Woman):
pty=1
def feel(self):
print("天热了,光屁股7")
super().feel()
print("天冷了,穿棉袄8")
obj = Son()
obj.feel()
"""
天热了,光屁股7
天热了,光膀子3
天热了,脱衣服5
天热,脱1
1
天冷,穿虎皮2
天冷了,穿羽绒服6
天冷了,穿羽绒服4
天冷了,穿棉袄8
"""
lst=Son.mro() #查看 super()对象调用顺序
print(lst)
"""
[
<class '__main__.Son'>,
<class '__main__.Man'>,
<class '__main__.Woman'>,
<class '__main__.Human'>,
<class 'object'>
]
"""
# 3.相关函数
# 1.issubclass 判断谁是否是谁子类
"""
在判断子父关系时,只要在一条继承链上,就有继承关系
语法:
1.issubclass(子类,父类) 满足返回True
2.issubclass(子类,(父类1,父类2,....)) 只要满足一个就返回True
"""
res=issubclass(Son,Man) #True
res=issubclass(Son,Human) #True
print(res)
# 2.isinstance 判断对象是否是这个类(对象与类之间的关系)
"""
在判断对象类型时,只要在一条继承链上,就有继承关系
语法与issubclass一样
"""
class Car():
pass
obj = Son()
print(isinstance(obj,Man)) #True
print(isinstance(obj,Human)) #True
print(isinstance(obj,Car)) #False
print(isinstance(obj,(Car,Human)))#True
2.多态
# 1.多态
"""
多态: 不同的子类对象,调用相同的父类方法,产生不同的执行结果
特征: 继承,重写,针对于对象
作用: 在公司中,统一命名规则
"""
class Soldier(): #士兵
def attack(self): #攻击
pass
def back(self): #撤退
pass
class Army(Soldier): #陆军
def attack(self):
print("包子雷")
def back(self):
print("轻功水上漂")
class Navy(Soldier): #海军
def attack(self):
print("鱼叉")
def back(self):
print("水遁")
class AirForce(Soldier):
def attack(self):
print("导弹")
def back(self):
print("跳伞,落地成盒")
# 创建陆军士兵
objArmy=Army()
# 创建海军士兵
objNavy=Navy()
# 创建空军士兵
objAirForce=AirForce()
# 整装待发
lst=[objArmy,objNavy,objAirForce]
strvar="""
1.全军出击
2.全体撤退
3.陆军掩护其他兵种撤退
各就各位,将军请下令:
"""
num=input(strvar)
for i in lst:
if num=="1":
i.attack()
elif num=="2":
i.back()
elif num=="3":
if isinstance(i,Army):
i.attack()
else:
i.back()
else:
print("听不清~~")
break