python2中面向对象的多继承是,python面向对象中的继承有什么特点
本章内容
Python中面向对象多态和继承的比较
=========================================
在OOP编程中,当我们定义一个类时,我们可以从一个现有的类中继承。新类称为子类,继承的类称为基类、父类或超类。
例如,我们编写了一个名为Animal的类,它有一个可以直接打印的run()方法:
动物类(物体):
定义运行(自身):
打印“动物正在奔跑…”
当我们需要编写狗和猫的类时,我们可以直接从动物类继承:
犬类(动物):
及格
类别猫(动物):
对于pass Dog,Animal是其父类,对于Animal,Dog是其子类。和猫狗差不多。
继承有什么好处?最大的好处是子类得到了父类的所有功能。当Animial实现run()方法时,Dog和Cat作为它的子类,不做任何事情就自动拥有run()方法:
狗=狗()
dog.run()
猫=猫()
cat.run()的运行结果如下:
动物正在奔跑.
动物正在奔跑.当然,你也可以给子类添加一些方法,比如Dog类:
犬类(动物):
定义运行(自身):
打印“狗在跑…”
定义吃(自己):
印刷‘吃肉’的第二个好处.继承要求我们对代码进行一些改进。正如你所看到的,无论是狗还是猫,当它们奔跑时(),它们显示动物正在奔跑.合乎逻辑的做法是显示狗在跑.猫在跑.分别是。因此,dog和cat类改进如下:
犬类(动物):
定义运行(自身):
打印“狗在跑…”
类别猫(动物):
定义运行(自身):
打印“猫在跑…”再次运行,结果如下:
狗在跑.
猫在跑.
当子类和父类中都存在相同的run()方法时,我们说子类的run()覆盖了父类的run(),代码运行时总会调用子类的run()。这样,我们得到了继承的另一个好处:多态性。
为了理解什么是多态性,我们必须首先解释数据类型。当我们定义一个类时,我们实际上定义了一个数据类型。我们定义的数据类型和Python自己的数据类型没什么区别,比如str、list、dict:
A=list() # a是一种列表类型。
B=Animal() # b是一种动物类型
C=Dog() # c是狗的类型
变量是否是某种类型可以通过isinstance()判断:
isinstance(a,列表)
真实的
isinstance(b,动物)
真实的
isinstance(c,Dog)
看来真的A,B,C确实对应了三种类型的列表,动物和狗。
但是等等,试试这个:
isinstance(c,动物)
但如果你仔细想想,这是有道理的,因为狗是由动物遗传而来的。当我们创建Dog的实例C时,我们认为C的数据类型是Dog是事实,但C也是动物也是事实。狗本来就是一种动物!
因此,在继承关系中,如果实例的数据类型是子类,那么它的数据类型也可以视为父类。然而,反之则不然:
b=动物()
isinstance(b,狗)
真狗可以被视为动物,但动物不能被视为假狗。
为了理解多态性的好处,我们还需要编写另一个函数来接受动物类型的变量:
def run_twice(动物):
animal.run()
animal.run()
当我们传入一个Animal实例时,run_twice()打印出:
run_twice(Animal())
动物正在奔跑.
动物正在奔跑.当我们传入一个Dog实例时,run_twice()输出:
run_twice(Dog())
狗在跑.
狗在跑.当我们传入一个Cat实例时,run_twice()打印出:
运行两次(Cat())
猫在跑.
猫跑.看起来并不有趣,但是如果你仔细想想,现在,如果我们定义另一种乌龟,它也来自动物:
龟类(动物):
定义运行(自身):
打印‘乌龟跑得很慢……’
当我们调用run_twice()时,我们传入一个Tortoise的实例:
run_twice(乌龟())
乌龟跑得很慢.
乌龟跑得很慢.你会发现,通过添加一个新的Animal子类,你不必对run_twice()做任何修改。事实上,任何依赖于Animal作为参数的函数或方法,不需要修改就可以正常运行,原因就在于多态。
多态的好处是当我们需要传入狗、猫、龟.我们只需要接收动物类型,因为狗、猫、乌龟.都是动物类型,然后,我们可以根据动物类型进行操作。因为Animal类型有run()方法,所以任何传入的类型,只要是Animal类或者子类,都会自动调用实际类型的run()方法,也就是多态:
对于一个变量,我们只需要知道它是一个动物类型,不需要确切知道它的子类型,就可以放心地调用run()方法。具体调用的run()方法是作用于动物、狗、猫还是乌龟对象取决于运行时对象的确切类型。这就是多态的真正威力:调用者只管调用,不管细节,当我们添加一个新的Animal子类时,这就是著名的“开闭”原理:
开放扩展:允许新的动物子类;
关闭修改:不需要修改依赖于动物类型的函数如run_twice()。
继承也是可以一级一级继承的,就像爷爷到爸爸到儿子的关系。而且任何一个类最后都可以追溯到根类对象,这些继承关系看起来就像一棵倒过来的树。例如,下面的继承树:
总结
继承可以直接取父类的所有功能,这样就不用从头开始了。子类只需要添加自己唯一的方法,也可以覆盖重写不适合父类的方法。
有了继承,就可以有多态性。调用类实例方法时,尽量把变量当作父类类型,这样所有子类都能正常接收;
在Python3中,如果没有合适的类继承,就从object类继承。
转载请联系作者取得转载授权,否则将追究法律责任。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。