继承
通过__init__类构造方法我们可以看出,我们定义出来的盖伦类和瑞文类存在代码冗余的现象,而我们写程序,最好是以简洁为目的。如果两个程序都能达到相同的目标,一个五百行代码,而另一个只有三百行代码,毫无疑问我们选择后者。而且这也很方便我们查阅修改。
所谓继承,就是重用现有类的功能,并在此基础上进行扩展,将相关类的共性进行抽象、统一概念,隔离变化。
小明:“不会讲话你就多讲点。”
简单地说,在python中,新建的类可以继承一个或者多个类。父类又可以称为基类或者超类,新建的类称为派生类或者子类。
简单地说,在python中,新建的类可以继承一个或者多个类。父类又可以称为基类或者超类,新建的类称为派生类或者子类。
继续昨天的盖伦类和瑞文类:
继承的原理(了解)
那么Python到底是如何实现继承的呢?
对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的为止。而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,只需要知道C3算法计算出来的列表,我找属性应该遵循什么样的原则:1、子类会先于父类被检查;
2、多个父类会根据它们在MRO列表中的顺序被检查;3、如果下一个类存在两个合法的选择(父类里面有重名的)选择第一个父类。
Python当中这个列表的产生,决定了你属性查找的方式,这个查找的方式分成两种:
深度优先(先深入继承树左侧查找,然后再返回,开始查找右侧)和广度优先(先从左到右水平方向上查找,最后再深入继承树右侧查找)。本质查找还是按照MRO列表,深度优先和广度优先的区别就是排列方式不一样。
在Python中类是分为两种的,新式类和经典类。这个区分只有pyhon2中才有,在python3里面已经没有经典类一说,都是新式类。
那么到底什么是新式类、经典类?
python2才有新式类和经典类的概念(继承了object的类就是新式类,反之就是经典类)。python3统一都是新式类,也就是都继承了object。
小明:“那个,那个,那个什么object的玩意儿是什么东西?”
Toranto:“我也不知道...”
小明:“来,吃药。”
在Python2中,默认都是经典类,只有显示继承了object的才是新式类:
在Python3中,取消了经典类,默认都是新式类,并且新式类不需要显示继承object对象。如下,这三种写法都可以,无区别:
多态
我们都知道,在python中,当一个变量被多次赋值的时候,它的传达结果会表现为最后一次赋值,这是很典型的弱语言。
我们先后调用了Dog和Cat中的eat方法,a被先后赋值为“吃骨头”,“吃鱼”,但这并不是多态。
类的多态特性,需要满足以下两个条件:
1、继承:多态一定是发生在父类和子类之间;
2、重写:子类重写了父类的方法。
可以看到,Dog和Cat都继承自Animal类,且各自都重写了父类eat()方法。从运行结果可以看出,同一变量 a 在执行同一个 say() 方法时,由于 a 实际表示不同的类实例对象,因此 a.say() 调用的并不是同一个类中的 say() 方法,这就是多态。
换句话说,子类一旦重新定义了自己的属性或方法且与父类重名,那么调用新增的属性或方法时,就以自己为准了。
但有时候,在多态形成之后,我们又需要重新调用父类的同名方法时,我们有两个选择:
方法一:“指名道姓”地调用某个类的功能(函数)。
方法二:super(),调用super()会得到一个特殊的对象,该对象专门用来引用父类的属性。
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !