day23:单继承&多继承&菱形继承&__init__魔术方法
目录
单继承
关于继承的一些基本概念
1.什么是子类?什么是父类?如果一个类继承另外一个类,该类叫做子类(衍生类),被继承的类叫做父类(基类,超类)
2.继承的种类:1.单继承 2.多继承
3.object类:在python中,所有的类都默认继承父类object
定义一个Human类,并定义一些属性和方法:
class Human(object): hair = "黑色" sex = "男" def cry(self): print("人类会哭") def eat(self): print("人类会吃东西") def __makebaby(self): print("人类会繁衍生息")
子父继承之后,子类可以调用父类的公有成员
# 1.子父继承之后,子类可以调用父类的公有成员 class Man(Human): # 定义Man类,继承Human类 pass obj = Man() print(obj.hair) # 子类Man直接调用父类的hair属性 obj.cry() # 子类Man直接调用父类的cry方法
子父继承之后,子类不能调用父类的私有成员
# 2.子父继承之后,子类不能调用父类的私有成员 class Woman(Human): def pub_func(self): self.__makebaby() obj = Woman() obj.__makebaby() # error 子类无法直接调用父类的私有成员 obj.pub_func() # error 即使在子类定义pub_func用来存放私有成员,那也是父类的私有成员,而非子类的
子父继承之后,子类可以改写父类中的方法
子父继承之后
1.如果子类里面有该成员属性或者方法,优先调用自己的
2.如果子类没有该成员,则调用父类中的成员
3.如果子类父类都没有该成员,则直接报错
class Children(): sex = "女" def cry(self): print("小孩会哇哇哇哭") obj = Children() obj.cry() # 子类有cry方法,优先使用子类的
多继承
多继承的基本语法
# 1.基本语法 class Father(): property = "爸爸英姿飒爽" def f_hobby(self): print("爸爸喜欢抽烟") class Mother(): property = "妈妈倾国倾城" def m_hobby(self): print("妈妈喜欢打麻将") class Daughter(Father,Mother): # Daughter类继承Father类和Mother类 pass # 实例化对象 obj = Daughter() print(obj.property) # 优先会继承Father类的property obj.m_hobby() # 妈妈喜欢打麻将
super用法
1.super本身是一个类,super()是一个对象,用来调用父类的绑定方法
2.super()只应用在绑定方法中,默认自动传递self对象(前提super所在作用域存在self)
3.super用途:解决复杂的多继承调用顺序
class Father(): property = "爸爸英姿飒爽" def f_hobby(self): print("爸爸喜欢抽烟") class Mother(): property = "妈妈倾国倾城" def m_hobby(self): print("妈妈喜欢打麻将") class Son(Father,Mother): property = "儿子喜欢玩游戏" # 1.利用类来调用父类的成员 def skill1(self): Father.f_hobby() print(Mother.property) # 2.利用对象调用父类的成员 def skill2(self): self.m_hobby() print(self.property) # 3.利用super调用父类的属性和方法 """ super()只调用父类的相关公有成员,不会调用自己的本类成员,父类没有直接报错 super()在调用父类方法时,只调用父类的绑定方法,默认传递参数是本类的对象self """ def skill3(self): print(super().property) super().m_hobby() obj = Son() obj.skill1() obj.skill2() obj.skill3()
self和super的区别
self和super()的区别:
self在调用成员时,先看看自己的类对象是否存在该成员
1.如果有调用自己的.
2.如果子类自己没有,调用父类的
3.如果子类和父类都没有,则直接报错
super()在调用成员时,只调用父类的相关成员(属性,绑定方法)
永远不会调用自己的,如果父类没有,直接报错
菱形继承(钻石继承)
super:用来解决复杂的多继承调用顺序
class OldWoman(): pass class Human(): pty = 4 def feelT(self): print("原始人类热了,吃冰块1") print(self.pty) print("原始人类冷了,生火取暖2") class Man(Human): pty = 3 def feelT(self): print("现代男人热了,光膀子3") super().feelT() print("现代男人冷了,穿大棉袄4") class Woman(Human): pty = 2 def feelT(self): print("现代女人热了,吹空调5") super().feelT() print("现代女人冷了,喝热水6") class Children(Man,Woman): pty = 1 def feelT(self): print("现代小孩热了,哇哇哭7") super().feelT() print("现代小孩冷了,也要哭8") obj = Children() obj.feelT()
执行顺序是73512648,继承顺序Children->Father->Mother->Human
执行完毕之后还需要将每个类中的feelT方法中剩余的代码执行完
整个代码的执行顺序像递归中"一来一回"的过程
mro列表:返回调用顺序列表
mro列表:super用途的一个体现,解决复杂的多继承调用顺序关系
类.mro() 返回的是方法调用顺序列表,针对于多继承下的同名方法,按照顺序依次的进行调用
lst = Children.mro() print(lst) """ [ <class '__main__.Children'>, <class '__main__.Man'>, <class '__main__.Woman'>, <class '__main__.Human'>, <class 'object'> ] """
issubclass 判断子父关系 (应用在类当中,判断子父关系)
# issubclass 判断子父关系 (应用在类当中,判断子父关系) """只要在一条继承链上即可(有血缘关系)""" res = issubclass(Children,Man) print(res) res = issubclass(Children,Woman) print(res) res = issubclass(Children,Human) print(res) res = issubclass(Children,(Human,Woman,Man,OldWoman)) print(res) res = issubclass(Children,OldWoman) print(res)
isinstance (应用在对象和类之间,判断类型)
# isinstance(应用在对象和类之间,判断类型) """只要在一条继承链上即可(有血缘关系)""" res = isinstance(obj,Children) # True res = isinstance(obj,Human) # True res = isinstance(obj,(Human,Children,Woman)) # True res = isinstance(obj,OldWoman) # False
问题:打印的值是多少?
如图所示:
魔术方法之__init__方法
__init__方法简介
1.触发时机:实例化对象,初始化的时候触发
2.功能:为对象添加成员
3.参数:参数不固定,至少一个self参数
4.返回值:无
基本语法
# 1.基本语法 class MyClass(): def __init__(self): print("初始化方法被触发") # 为当前对象self添加成员name self.name = "Mike" # 实例化对象 obj = MyClass() # 初始化方法被触发 print(obj.name) # Mike
带有多个参数的构造方法
# 2.带有多个参数的构造方法 class MyClass(): def __init__(self,name): # self.成员名 = 参数 self.name = name # 实例化对象 obj = MyClass("Mike") # 在实例化对象的时候,给构造方法传递参数 print(obj.name) # Mike
类可以是一个,对象可以是多个
1.一个类可以实例化多个不同的对象
2.对象和对象之间彼此独立
3.但都可以使用类中的公有成员
class Children(): def __init__(self, name, skin): self.name = name self.skin = skin def cry(self): print("小孩一出生就哇哇哇的哭") def drink(self): print("小孩一下生就要喝奶奶") def __la(self): print("小孩拉粑粑是私有的") def pub_info(self): print("该对象的名字是{},该对象的肤色是{}".format(self.name, self.skin)) # 创建第一个小孩 afanda = Children("阿凡达", "蓝色的") afanda.pub_info() afanda.cry() # 创建第二个小孩 afanti = Children("阿凡提", "黄色的") afanti.pub_info() afanti.drink() # 创建第三个小孩 bao = Children("我滴宝强", "绿色的") bao.pub_info() # bao.__la() # 无法在类外调用私有的成员