概述
目录
一、面向对象编程的三大特征
二、什么是多态
三、实现多态的步骤
1.Python中函数的参数是没有类型限制的
2.子类的对象是不是属于这个父类
3.实现伪多态
四、多态的意义
五、鸭子类型
1.鸭子类型的体现
2.代码实现鸭子类型
一、面向对象编程的三大特征
封装,继承,多态。
封装:将数据和方法放在一个类中就构成了封装。
继承:Python中的一个类可以继承一个类也可以继承多个类,被继承的类叫父类(或者叫基类,base class ),继承的类叫子类。
多态(Polymorphism):指的是一类事物有多种形态,一个抽象类有多个子类(因而多态的概念依赖于继承),不同的子类对象调用相同的方法,产生不同的执行结果,多态可以增加代码的灵活度。
定义一个类,它就是封装。通过类,可以将类里面的一些属性和方法封装在一起。子类继承父类,可以获得父类里面的属性和方法,这个就叫做继承。
二、什么是多态
严格来说,Python中是没有多态的,但是Python中可以实现伪多态,Python中函数的参数是没有类型限制的。Python中有个鸭子类型,比多态更厉害。
多态是建立在继承的基础上的。指的是一类事物有多种形态,其实就是一个父类有多个子类。
父类里面有某个方法,在子类中同样也有这个方法。但是在子类中有这个方法体现的形式和父类中不一样。
在调用这个父类,它所有的子类对象里面,同样是调用同一个方法。因为是不同的子类,所以执行的内容、结果、功能不一样,这就是多态。
多态是建立在继承的基础上的。
三、实现多态的步骤
1.定义一个父类(Base),实现某个方法(比如:run)。
2.定义多个子类,在子类中重写父类的方法(run),每个子类run方法实现不同的功能。
3.假设我们定义了一个函数,需要一个Base类型的对象的参数,那么调用函数的时候,传入Base类不同的子类对象,那么这个函数就会执行不同的功能,这就是多态的体现。
Python中实现的多态是伪多态。Python中定义一个函数,只要函数给它传参数,对于函数的参数是没有类型限制的。
c和java定义一个函数,函数的参数是有类型限制的。指定这个函数的参数只能传什么类型。
1.Python中函数的参数是没有类型限制的
定义一个函数,调用的时候可以传字符、数值、列表。a这个参数没类型限制,传个类进去也行,传个函数进去也可以,传个对象进去也可以,传什么都可以,没有类型限制。
#Python中函数的参数是没有类型限制的。
def func(a):
print(a)
func(122)
func('1213')
func([12,22])
2.子类的对象是不是属于这个父类?
假如Python是个强类型语言。函数只能传父类(Base)这个类型的数据。接下来子类的对象是不是属于这个父类?
# 伪多态的实现。
class Base(object):
def run(self):
print("__base___run___:慢慢走路")
class Cat(Base):#继承Base。
def run(self):#同样里面也有run()方法。
print("___cat___run___:会爬树")
class Dog(Base):
def run(self):
print("___dog___run___:跑得特别快")
b_obj=Base()
c_obj=Cat()
d_obj=Dog()
print(isinstance(c_obj,Base))
多态是建立在继承的基础上,同样多态要重写。
子类的对象c_obj是不是属于父类的类型?
子类所创建出来的对象也属于父类的类型。
3.实现伪多态
假设func()的参数需要Base类型的。Cat和Dog这个子类创建出来的对象也是属于Base类型的。
class Base(object):
def run(self):
print("__base___run___:慢慢走路")
class Cat(Base):
def run(self):
print("___cat___run___:会爬树")
class Dog(Base):
def run(self):
print("___dog___run___:跑得特别快")
class Pig(Base):#同样也继承于Base
pass#这个里面没有任何方法。
b_obj=Base()
c_obj=Cat()
d_obj=Dog()
p_obj=Pig()
# 子类的对象是属于父类的类型。
# print(isinstance(c_obj,Cat))
# print(isinstance(c_obj,Base))
#Python中函数的参数是没有类型限制的。
# 假设func的参数需要Base类型的。
def func(base_obj):
base_obj.run()
func(b_obj)
func(c_obj)
func(d_obj)
func(p_obj)#这个类创建出来的对象,它传进去的时候,它里面没有run()方法,调用父类的run方法。
# func(122)
# func('1213')
# func([12,22])
这个就是个多态。一类事物有不同的形态。传进去的b_obj、c_obj、d_obj、p_obj都是属于Base这个类型的。
Base这个父类有很多个子类。参数限定的时候,限定的是Base这个类。
但是如果传入不同子类,同样的方法传入这个类型的对象。因为是不同的子类创建出来的,它会执行不同的功能。
有一个不同的体现,那么这种就叫做多态。
注意:Python中函数的参数是没有类型限制的,所以多态在Python中的体现并不是很严谨。多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。
不修改原来已经实现的功能代码,通过继承扩展新的功能:
不修要修改原来已经实现的功能代码,通过继承扩展新的功能。重新定义方法,变成另外一种形态:
# 伪多态的实现。
class Base(object):
def run(self):
print("__base___run___:慢慢走路")
class Cat(Base):
def run(self):
print("___cat___run___:会爬树")
class Dog(Base):
def run(self):
print("___dog___run___:跑得特别快")
class Pig(Base):#同样也继承于Base
def run(self):
print("这是一个幂运算")
class CCC(Base):
def run(self):#重新定义方法,变成另外一种形态。
print("cccc功能")
b_obj=Base()
c_obj=Cat()
d_obj=Dog()
p_obj=Pig()
c=CCC()
# 子类的对象是属于父类的类型。
# print(isinstance(c_obj,Cat))
# print(isinstance(c_obj,Base))
#Python中函数的参数是没有类型限制的。
# 假设func的参数需要Base类型的。
def func(base_obj):
base_obj.run()
func(b_obj)
func(c_obj)
func(d_obj)
func(p_obj)
func(c)
# func(122)
# func('1213')
# func([12,22])
在Python里面这个是伪多态的实现。
四、多态的意义
多态的意义:开放封闭的原则。
对于一个变量,我们只需要知道它是Base类型,无需确切地知道它的子类型,就可以放心地调用run()方法,(调用方只管调用,不管细节)。
当需要新增功能,只需要新增一个Base的子类实现run()方法,就可以在原来的基础上进行功能扩展,这就是著名的“开放封闭”原则:
对扩展开放:允许新增Base子类。
对修改封闭:不需要修改依赖Base类型的run()等函数。
五、鸭子类型
鸭子类型概念: 它并不要求严格的继承体系,关注的不是对象的类型本身,而是它是如何使用的,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。
1.鸭子类型的体现
静态语言:对于静态语言(jave,C#)来讲上面传入的对象必须是Base类型或者它的子类,否则,将无法调用run()方法。
动态语言:对于动态语言Python来讲,上面传入的并不一定要Base类型,也可以是其它类型,只要在内部实现一个run()方法就行了,这就是鸭子类型的体现。
2.代码实现鸭子类型
定义个类不继承Base,在里面定义个run()方法,把MyClass这个类创建个对象。调用这个函数,把m传进去,同样也可以调用。
# 伪多态的实现。
class Base(object):
def run(self):
print("__base___run___:慢慢走路")
class Cat(Base):
def run(self):
print("___cat___run___:会爬树")
class Dog(Base):
def run(self):
print("___dog___run___:跑得特别快")
class Pig(Base):#同样也继承于Base
def run(self):
print("这是一个幂运算")
class CCC(Base):
def run(self):#重新定义方法,变成另外一种形态。
print("cccc功能")
class MyClass(object):#这个类不继承Base
def run(self):
print("是myclass的run方法")
b_obj=Base()
c_obj=Cat()
d_obj=Dog()
p_obj=Pig()
c=CCC()
m=MyClass()
# 子类的对象是属于父类的类型。
# print(isinstance(c_obj,Cat))
# print(isinstance(c_obj,Base))
#Python中函数的参数是没有类型限制的。
# 假设func的参数需要Base类型的。
def func(base_obj):
base_obj.run()
func(b_obj)
func(c_obj)
func(d_obj)
func(p_obj)
func(c)
func(m)
# func(122)
# func('1213')
# func([12,22])
像java和c这种强类型的语言,多态的意义在于参数有类型的限制,限制只能传入某个类型的参数,某个类型对象的数据。那么接下来传数据的话只能传这个类型,或者传它的子类。
在Python里的参数没类型限制的。也就是说不用多态照样能够实现,只要定义一个类,类里面有这个run()方法就行了。
因为传进去的对象在里面调用的是run()方法,自己定义一个类,类里面只要有run()方法,那么就都能够放在这个函数例如func()里面去调用。不会报错,有run()方法就行了。不继承它也可以。这叫做鸭子类型。
自己定义的类里面,只要实现了这个里面的方法:
Python中的多态都是伪多态,因为函数的参数都没类型限制,严格意义来说就没有多态。多态和鸭子类型差不多。Python的鸭子类型开放性更好,只要对象里面实现了某个方法,看起来和它一样可以用就行了。
Python中鸭子类型:新定义一个类,在类里面同样实现这个方法,在方法里面写一些不同的代码,同样是调用这个函数,同样是传一个对象,可以做一些不同的事情。
最后
以上就是寂寞奇异果为你收集整理的Py测开《多态和鸭子类型的区别》目录的全部内容,希望文章能够帮你解决Py测开《多态和鸭子类型的区别》目录所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复