面向对象三大特性之继承
-
什么是继承
-
继承是一种创建新类的方式,新建的类可以继承一个或者多个父类(python支持多继承),父类又可以称为基类又或超类,新建的类称为派生类或者子类.
-
子类会'遗传'父类的属性(特征和技能),从而解决代码重用的问题
-
class Father: # 父类 height = tall class Son(Father): # 子类,需要将父类传入 pass print(Son.height) #子类直接调用的父类中的属性
-
继承与抽象
-
继承描述的是子类与父类之间的关系,是子类可以用父类中所有属性的方式,所以要对父类进行抽取,不能出现子类不应该有的属性,即抽象
-
抽象是一种概念性的描述方式,表达的是抽取子类中共同的相似点,新建出一个公共父类.抽象的主要的作用是划分类别(达到隔离关注点,降低复杂度的目的)
-
所以在编程中与要先分析公共属性抽象后,再继承建立子类
-
-
派生
-
派生类 : 子类中除有父类中公用的属性外,还应该有自己独特的属性,这种含有自己独特属性的子类被称之为派生类
-
注意:一旦重新定义了自己的属性且与父类重名,那么调用重定义属性时,就以自己为准.
即子类中出现了与父类重复的名字,称之为覆盖, 子类出现了与父类不同的名字 称之为派生
-
-
子类中调用父类中的方法
方法一: 指名道姓,即父类名.父类方法()
方法二:super() 表示创建一个特殊的对象 用于调用父类的方法
!--了解:在python2中super的使用方式有所不同,需要传入当前类和当前对象--
# 方法一:指名道姓 class Human: def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex print(self) def sayhello(self): print('hello 我是%s 今年%s岁 性别:%s' % (self.name, self.age, self.sex)) class Student(Human): def __init__(self, name, age, sex, number): Human.__init__(name, age, sex) self.number = number def sayhello(self): print('heeeello...') Human.sayhello(self) stu1 = Student('JASSON', 18, 'Male', '123') stu1.sayhello() # 输出结果 heeeello... hello 我是JASSON 今年18岁 性别:Male # 方法二:super() ... class Student(Human): def __init__(self, name, age, sex, number): # 在python中super()等同于super(Human,self),而super(Human,self)就相当于实例本身 super().__init__(self, name, age, sex) self.number = number def sayhello(self): print('heeeello...') Human.sayhello(self) # 输出结果 heeeello... hello 我是JASSON 今年18岁 性别:Male 注意: 当你使用super()函数时,Python会在MRO列表上继续搜索下一个类。只要每个重定义的方法统一使用super()并只调用它一次,
那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次(注意注意注意:使用super调用的所有属性,都是从MRO列表当前
的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表) -
存在继承关系后的属性/方法查找
-
优先查找对象,对象中没有就查找类,类中没有就查找父类,知道不存在父类时都没找到则报错.
-
(了解内容)存在多个父类时的属性查找顺序:
-
第一种情况:
按照定义中传入父类的先后顺序查找
-
-
-
第二种情况:
-
存在父类不存在共同父类时(树状结构):深度优先,按照传入父类的顺序查到底,如果没有则查找下一条线,直到查到或查不到报错
-
-
存在的父类存在共同父类时(菱形结构):广度优先,先按照传入父类的顺序查,止步于最后的公共父类,直到所有对象的父类查找完毕后最后查找公共父类.
-
-
菱形结构与树状结构的组合(混合结构):将菱形结构整体看做树状结构的一种,其内部仍然以菱形结构查找,查找完毕后进行树状结构.
-
-
-
-
经典类与新式类
-
新式类:所有直接继承或者间接继承object的类 都是新式类
object 称之为根类,意思是所有类都源自与object类
这么设计的目的:object提供了一些常用的基础操作
-
注意:
-
python 3中默认所有类都是新式类
-
python 2中默认是经典类(不会自动继承object)
-
-
-
mro
-
子类名.mro ():表示属性的查找顺序列表,属性查找就是按照该列表来查找的
-
""" super访问父类内容时 按照mro列表属性查找 """ class S: def f1(self): print("s f1") class A(S): pass class B(S): def f1(self): print("b f1") pass class C(A, B): def f2(self): print("c f2") super().f1() print(C.mro()) # 输出结果 (从左到右即为查找顺序) [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.S'>, <class 'object'>]