文章目录
1、继承
1.1、类的继承
class Animal:
def eat(self):
print("吃东西")
def breathe(self):
print("呼吸")
class Fish(Animal):
def breathe(self):
print("鱼用腮呼吸")
if __name__ == '__main__':
fish = Fish()
fish.eat()
fish.breathe()
输出:
吃东西
鱼用腮呼吸
1.2、接口继承
- 接口不能实例化
- 接口的派生类必须实现基类中的全部函数
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def eat(self):
'''吃'''
pass
@abc.abstractmethod
def breathe(self):
'''呼吸'''
pass
class Fish(Animal):
def eat(self):
print("鱼吃东西")
def breathe(self):
print("鱼用腮呼吸")
if __name__ == '__main__':
fish = Fish()
fish.breathe()
1.3、类的继承顺序
1.3.1、 经典类和新式类
- Python2.x中,默认都是经典类,只有显式继承了object才是新式类
- Python 3.x中取消了经典类,默认都是新式类,并且不必显式的继承object。
- 经典类遵循深度优先的规则
- 新式类遵循广度优先的规则
- 新式类从Python2.2开始的
- 新式类的出现改变了经典类中一个多继承的bug, 因为其采用了广度优先的算法
Python2.x中经典类和新式类的定义如下:
#Python2.x中经典类和新式类的定义如下
class Person(object):pass #新式类写法
class Person():pass #经典类写法
class Person:pass #经典类写法
Python3.x中经典类和新式类的定义如下:
#Python3.x中取消了经典类,默认都是新式类
#以下三种写法无区别
class Person(object):pass
class Person():pass
class Person:pass
1.3.1、经典类和新式类的继承顺序
- 经典类遵循深度优先的规则
- 新式类遵循广度优先的规则
1.3.2、深度优先
- D是继承B和C的,
- 按照顺序,首先去找B,
- 如果在B里面能找到实例化对象,便继承B,不再往别的地方寻找
- 如果没有,就会接着找A
- 查找顺序为D===>B===>A===>C
1.3.3、广度优先
- D是继承B和C的,
- 按照顺序,首先去找B,
- 如果在B里面能找到实例化对象,便继承B,不再往别的地方寻找
- 如果没有,就会接着找C,而不是找B的父亲A
- 查找顺序为D===>B===>C===>A
1.3.4、经典类中深度优先的BUG
- 经典类中如果都有save方法, C中重写了save() 方法, 那么寻找顺序是 D->B->A, 永远找不到C.save()
1.3.5、查看类的继承顺序
class A:
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
if __name__ == '__main__':
print(D.__mro__)
输出:
(<class ‘main.D’>, <class ‘main.B’>, <class ‘main.C’>, <class ‘main.A’>, <class ‘object’>)