在Python中,继承可以分为单继承、多继承和多层继承。
单继承
子类只继承一个父类,继承概念表示子类获得了父类的所有方法和属性。
继承语法
class 类名(父类名): pass
子类继承自父类,可以享受父类中已经封装好的方法,不需要再次定义。子类中应该根据职责封装子类特有的属性和方法。
继承具有传递性,例如Dog
类继承自Animal
,XiaoTianQuan
又继承自Dog
类,那么XiaoTianQuan
类就具有了Animal
类里的所有属性和方法。
子类拥有父类以及父类的父类中封装的所有属性和方法。
思考问题:
XiaoTianQuan
能否调用Animal
的run()
方法?XiaoTianQuan
能够调用Cat
里的方法吗?
多继承
子类可以拥有多个父类,并且具有所有父类的属性和方法。
语法格式
class 子类名(父类名1, 父类名2, ...) pass
使用多继承时需要注意以下事项
- 如果不同的父类中存在同名的方法,子类对象在调用方法时,会调用哪个父类的方法?应尽量避免这种容易产生混淆的情况。如果多个父类之间存在同名的属性或方法,应尽量避免使用多继承。
Python中的MRO
Python中针对类提供了一个内置属性__mro__
,可以用来查看方法的搜索顺序。MRO是method resolution order的简称,主要用于在多继承时判断方法属性的调用顺序。
示例代码如下:
print(C.__mro__)
输出结果为:
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
在调用方法时,按照__mro__
的输出结果从左至右的顺序查找:
- 如果在当前类中找到方法,就直接执行,不再向下搜索。
- 如果没有找到,就顺序查找下一个类中是否有对应的方法,如果找到,就直接执行,不再继续向下搜索。
- 如果找到了最后一个类,依然没有找到方法,程序就会报错。
新式类和旧式(经典)类
object
是Python中所有对象的基类,提供了一些内置的属性和方法,可以使用dir
函数查看。
- 新式类:以
object
为基类的类,推荐使用。 - 经典类:不以
object
为基类的类,不推荐使用。
在Python3.x以后定义类时,如果没有指定父类,这个类会默认继承自object
,所以,Python3.x版本定义的类都是新式类。
在Python2.x中定义类时,如果没有指定父类,则不会继承自object
。
为了保证代码在Python2.x和Python3.x中都能够运行,在定义类时,如果一个类没有父类,建议统一继承自object
。
示例代码:
class 类名(object): pass