当前位置:
首页 >
类的多态
发布时间:2025/7/14
66
豆豆
#我们前面了解了继承,继承可以帮助我们重复使用代码。但对于继承中的示例,无论是Dog还是Cat,调用父类的run()方法时显示的都是Animal is running.,如果想让结果显示为Dog is running.和Cat is running.,该如果处理呢? #我们对Dog和Cat做如下改进: 1 #! /usr/bin/python3
2 #-*-coding:UTF-8-*-
3 #clas_多态
4
5 class Animal(object):
6 def run(self):
7 print('Animal is running.')
8
9 class Dog(Animal):
10 def run(self):
11 print('Dog is running.')
12
13 class Cat(Animal):
14 def run(self):
15 print('Cat is running.') #执行如下语句: 1 dog=Dog()
2 print('实例化Dog类')
3 dog.run()
4
5 cat=Cat()
6 print('实例化Cat类')
7 cat.run() #程序执行结果如下: 1 D:\Python\workspace\datatime\20171129>python class_多态.py
2 实例化Dog类
3 Dog is running.
4 实例化Cat类
5 Cat is running. #由执行结果看到,分别得到了Dog和Cat各自的running结果。 #当子类和父类存在相同的run()方法时,子类的run()方法会覆盖父类的run()方法,在代码运行时总会调用子类的run()方法,称之为多态。 #多态来自于希腊语,意思是有多种形式。多态意味着即使不知道变量所引用的对象类型是什么,也能对对象进行操作,多态会根据对象(或类)的不同而表现出不同的行为。例如,我们在上面的Animal类中定义了run方法,Dog和Cat分别继承Animal类,并且分别定义了自己的run方法,最后Dog和Cat调用的还是自己定义的run方法。 #为了更好了解什么是多态,我们对数据类型再做一个说明。当我们定义一个类时,实际上就是定义了一种数据类型。定义的数据类型和Python自带的数据类型(如str、list、dict)没什么区别。 1 #! /usr/bin/python3
2 #-*-coding:UTF-8-*-
3 #clas_多态
4
5 class Animal(object):
6 def run(self):
7 print('Animal is running.')
8
9 class Dog(Animal):
10 pass
11
12 a=list() #a是list类型
13 b=Animal() #b是Animal类型
14 c=Dog() #c是Dog类型 #下面用isinstance()方法判断一个变量是否是某个类型。 1 print('a是否是list类型:',isinstance(a,list))
2 print('b是否是Animal类型:',isinstance(b,Animal))
3 print('c是否是Dog类型:',isinstance(c,Dog)) #执行结果如下: 1 D:\Python\workspace\datatime\20171129>python class_多态.py
2 a是否是list类型: True
3 b是否是Animal类型: True
4 c是否是Dog类型: True #由执行结果看到,a,b,c确实分别为list、Animal、Dog三种类型。我们再执行如下语句: 1 print('c是否是Dog类型:',isinstance(c,Dog))
2 print('c是否是Animal类型:',isinstance(c,Animal)) #执行结果如下: 1 c是否是Dog类型: True
2 c是否是Animal类型: True #由执行结果看到,c既是Dog类型又是Animal类型,这怎么理解呢? #因为Dog是从Animal继承下来的,当我们创建Dog的实例c时,我们认为c的数据类型是Dog,但c同时也是Animal,Dog本来就是Animal的一种。 #在继承关系中,如果一个实例的数据类型是某个子类,那它的数据类型也可以看作是父类。但反过来就不行,例如如下语句: 1 print('b是否是Dog类型:',isinstance(b,Dog)) #执行结果如下: 1 b是否是Dog类型: False #由输出结果看到,变量b是Animal的实例化对象,是Animal类型,但不是Dog类型,也就是Dog可以看成Animal,但Animal不可以看成Dog。 #我们再看一个示例。编写一个函数,这个函数接收一个Animal类型的变量,定义并执行如下函数,执行时传入Animal的实例: 1 #! /usr/bin/python3
2 #-*-coding:UTF-8-*-
3 #class_多态_2
4
5 class Animal(object):
6 def run(self):
7 print('Animal is running.')
8
9 def run_two_times(animal):
10 animal.run()
11 animal.run()
12
13 run_two_times(Animal()) #执行结果如下: 1 D:\Python\workspace\datatime\20171129>python class_多态_2.py
2 Animal is running.
3 Animal is running. #若执行函数传入Dog的实例,操作如下: 1 #! /usr/bin/python3
2 #-*-coding:UTF-8-*-
3 #class_多态_2
4
5 class Animal(object):
6 def run(self):
7 print('Animal is running.')
8
9 class Dog(Animal):
10 def run(slef):
11 print('Dog is running.')
12
13 def run_two_times(animal):
14 animal.run()
15 animal.run()
16
17 run_two_times(Dog()) #得到的执行结果如下: 1 D:\Python\workspace\datatime\20171129>python class_多态_2.py
2 Dog is running.
3 Dog is running. #若传入Cat的实例,操作如下: 1 #! /usr/bin/python3
2 #-*-coding:UTF-8-*-
3 #class_多态_2
4
5 class Animal(object):
6 def run(self):
7 print('Animal is running.')
8
9 class Dog(Animal):
10 def run(slef):
11 print('Dog is running.')
12
13 class Cat(Animal):
14 def run(self):
15 print('Cat is running.')
16
17 def run_two_times(animal):
18 animal.run()
19 animal.run()
20
21 run_two_times(Animal())
22 run_two_times(Dog())
23 run_two_times(Cat()) #得到执行结果如下: 1 D:\Python\workspace\datatime\20171129>python class_多态_2.py
2 Animal is running.
3 Animal is running.
4 Dog is running.
5 Dog is running.
6 Cat is running.
7 Cat is running. #看上去没有什么特殊的地方,已经正确输出预期结果了,但仔细想想看,如果再定义一个Bird类型,也继承Animal类,定义如下: 1 #! /usr/bin/python3
2 #-*-coding:UTF-8-*-
3 #class_多态_2
4
5 class Animal(object):
6 def run(self):
7 print('Animal is running.')
8
9 class Dog(Animal):
10 def run(slef):
11 print('Dog is running.')
12
13 class Cat(Animal):
14 def run(self):
15 print('Cat is running.')
16
17 class Bird(Animal):
18 def run(self):
19 print('Bird if flying the sky.')
20
21 def run_two_times(animal):
22 animal.run()
23 animal.run()
24
25 run_two_times(Animal())
26 run_two_times(Dog())
27 run_two_times(Cat())
28 run_two_times(Bird()) #程序执行结果如下: 1 D:\Python\workspace\datatime\20171129>python class_多态_2.py
2 Animal is running.
3 Animal is running.
4 Dog is running.
5 Dog is running.
6 Cat is running.
7 Cat is running.
8 Bird if flying the sky.
9 Bird if flying the sky. #由执行结果看到,新增的Animal子类不必对run_two_times()方法做任何修改。实际上,任何依赖Animal作为参数的函数或方法都可以不加修改地正常运行,原因就在于多态。 #多态的好处是:当我们需要传入Dog、Cat、Bird等对象时,只需要接收Animal类型就可以了,因为Dog、Cat、Bird等都是Animal类型,按照Animal类型进行操作即可。由于Animal类型有run()方法,因此传入的类型只要是Animal类或继承自Animal类,都会自动调用实际类型的run()方法。 #多态的意思是:对于一个变量,我们只需要知道它是Animal类型,无需确切知道它的子类型,就可以放心调用run()方法。具体调用的run()方法作用于Anial、Dog、Cat或Bird对象,由运行该对象的确切类型决定。 #多态真正的威力在于:调用方只管调用,不管细节。当我们新增一种Animal的子类时,只要确保run()方法编写正确即可,不用管原来的代码如何调用的,这就是著名的“开闭”原则:对于扩展开放,允许新增Animal子类;对于修改封闭,不需要修改依赖Animal类型的run_two_times()等函数。 #很多函数和运算符都是多态的,也许你写的程序也可能时,即使你并非有意这样的。只要使用多态函数和运算符,多态就会消除。唯一能够毁掉多态的是使用函数显式地检查类型,如type、isinstance函数等,如果有可能,就尽量避免使用这些会毁掉多态的方式,重要的是如何让对象按照我们希望的方式工作,无论它是否是正确类型或类。
转载于:https://www.cnblogs.com/DLHe/p/7927394.html
总结
- 上一篇: 阿里代码规范插件 中文使用手册 FOR
- 下一篇: BWA SAM文件格式