一, 什么是继承
继承是一种创建类的方法, 在 python 中, 一个类可以继承来自一个或多个父. 原始类称为基类或超类.
- # 创建父类
- class Parent1:
- pass
- class Parent2:
- pass
- # 继承父类, 单继承
- class Obj1(Parent1):
- pass
- # 继承父类, 多继承
- class Obj2(Parent1,Parent2):
- pass
二, 什么时候使用继承
在已经创建的几个类中, 这几哥类中的方法和变量有相同的, 这种时候我们就可以使用类的继承, 将其它类中已有的方法和变量通过继承的方式, 在新创建的类中, 使用正常的方式就可以调用父类中的方法. 剩下自己特有的方法只要在自己类中定义就可以.
举个列子: 人都会吃, 喝, 玩, 小明也是一个人, 所以小明也会, 所以小明继承了人的属性, 特别的是小明还会背古诗, 就基于以上的说法写一个类的继承.
- class Man:
- def eat(self):
- print('吃')
- def drink(self):
- print('喝')
- def play(self):
- print('玩')
- class XiaoMing(Man):
- def recite(self):
- print('背古诗')
- xm = XiaoMing()
- xm.eat()
- xm.recite()
输出结果:
吃
背古诗
三, 单继承与多继承
单继承: 仅仅继承一个父类, 当查找方法的时候, 首先在自己里面查找, 然后到父类里面查找.
- class Biology:
- def split(self):
- print(self.name+"accrue")
- class Animal(Biology):# 在类后面加括号加上所要继承类的名字, 继承的是类的方法
- def GoWhoring(self):
- print("i like go whoring")
- def eat(self):
- print(self.name+"eat")
- class superman:
- def gamble(self):
- print("gamble is interesting")
- def GoWhoring(self):
- print("beautiful whoring")
- class Cat(Animal):
- def GoWhoring(self):
- print("i don't like go whoring")
- def __init__(self,name):
- self.name = name
- def cry(self):
- print(self.name + "喵")
- #优先级: 自己, 父类 (左边, 右边)
- class Dog(Animal,superman):# 在继承多个父类时, 在两个父类都有同一个名字的方法时, 优先选择括号左边的父类的方法
- def __init__(self,name):
- self.name = name
- def cry(self):
- print(self.name + "汪")
- mimi = Cat("mimi")
- mimi.eat()
- mimi.cry() #当基类里方法存在, 派生类里也存在同名方法, 优先找派生类里的方法
- mimi.GoWhoring() #当父类里有一个方法自己也有一个同名的方法时, 默认使用自己的方法
- husike = Dog("erha")# 虽然 Dog 里没有 eat 和 split 但是由于 Dog 继承了 Animal 和的方法, 而 Animal 继承了 Biology 的方法
- husike.eat() #所以 Dog 可以使用 Biology 的方法
- husike.cry() #父类有一个名字叫 "基类" 子类有一个名字叫 "派生类"
- husike.split()
- husike.GoWhoring()
- faker = Animal()
- faker.GoWhoring()# 优先使用自己的方法
派生类可以继承基类里的所有功能.
当基类里方法存在, 派生类里也存在同名方法, 派生类优先找派生类里的方法 (意思是优先找自己的).
在 Java,C# 里面一个子类只能继承一个父类, 多了报错, 但是在 python 里可以继承多个父类
在经典类中, 继承是以深度优先, 在新式类中, 继承是以广度优先.
Python 2.x 中默认都是经典类, 只有显式继承了 object 才是新式类.
python 3.x 中默认都是新式类, 经典类被移除, 不必显式的继承 object.
深度优先:
- class A():
- def save(self):
- print("This is from A")
- class B(A):
- pass
- class C(A):
- def save(self):
- print("This is from C")
- class D(B,C):
- pass
- fun = D()
- fun.save()
输出结果:
This is from A"
深度优先的时候就是一条道走到黑, 从左向右找, 先把左边的一个里面的全部找完在找右边的.
广度优先:
- class A():
- def save(self):
- print("This is from A")
- class B(A):
- pass
- class C(A):
- def save(self):
- print("This is from C")
- class D(B,C):
- pass
- fun = D()
- fun.save()
输出结果:
This is from C
首先在左边的上一层父类中寻找, 如果没有就到右边一个父类中寻找, 没有就到左边父类的父类中寻找.
广度优先多种情况解析
情况一
有 A,B,C,D,E 几个类, A 为 B 的父类, B 为 C 的父类, E 为 D 的父类, D 为 C 的父类 现在 C 需要使用一个方法, 只有在 A,E 里有, 第一次 C 先去 B 中寻找没有找到 然后就会去 A 里面找, A 里没有就去 D 里面找, 然后再去 E 里找.
- class A:
- def function(self):
- print("are you OK?A")
- class B(A):
- def function_fake(self):
- print("are you OK?B")
- class E:
- def function(self):
- print("are you OK?E")
- class D(E):
- def function_fake(self):
- print("are you OK?D")
- class C(B, D):
- def Sb(self):
- print("i am sb")
- faker = C()
- faker.function()
输出结果:
are you OK?A
括号里为查找顺序.
情况二
它会先把没有共同的父类寻找玩, 然后再找共同的父类, 因为在这种情况下它想找到和自己关系最近的.
- class S:
- def function(self):
- print('are you Ok?S')
- class A(S):
- def function_fake(self):
- print("are you OK?A")
- class B(A):
- def function_fake(self):
- print("are you OK?B")
- class E(S):
- def function(self):
- print("are you OK?E")
- class D(E):
- def function_fake(self):
- print("are you OK?D")
- class C(B, D):
- def Sb(self):
- print("i am sb")
- faker = C()
- faker.function()
输出结果:
are you OK?E
情况三
当 A,B,D,E, 都没有 C 所要找的函数时才会找右边的 F(括号右边)
- class F():
- def function(self):
- print("are you OK?F")
- class A:
- def function_fake(self):
- print("are you OK?A")
- class E:
- def function_fake(self):
- print("are you OK?E")
- class B(A,F):
- def function_fake(self):
- print("are you OK?B")
- class D(E):
- def function_fake(self):
- print("are you OK?D")
- class C(B, D):
- def Sb(self):
- print("i am sb")
- faker = C()
- faker.function()
输出结果:
are you OK?F
情况四
首先面执行一个 c1 = C();c1.xxx() ,xxx 在 D 里面而且 xxx 又执行了 self.ooo() 而 ooo 在 BDE 里都有它会执行哪个?
- class B:
- def ooo(self):
- print("B")
- class E:
- def ooo(self):
- print("E")
- class D(E):
- def xxx(self):
- self.ooo()
- def ooo(self):
- print("D")
- class C(B, D):
- pass
- c1 = C()
- c1.xxx()
输出结果:
B
解析: 首先找到 c1.xxx 在 D 里面, 在 D 里面又执行了 self.ooo(), 这个 self 代指 c1, 而 c1 为 C 类的对象, 意思还是 c1.ooo, 所以寻找 ooo 时还是从 C 开始, 因为先找左边的所以, 找到了 B 的 ooo 以后找是谁执行的函数要看准 self 到底是谁的从 self 下手.
红色为第二次寻找路径 (寻找 ooo 方法的次序)
今天的类的继承主要是多继承的时候父类中方法选择的.
来源: https://www.cnblogs.com/liudi2017/p/9297336.html